【问题标题】:Select node from XML and Create a new XML从 XML 中选择节点并创建一个新的 XML
【发布时间】:2013-11-06 14:44:48
【问题描述】:

我正在尝试剥离我的 XML 并仅保留 String Keep 数组中的节点

输入 XML 是

 <Employees>
  <Employee>
    <EmpId>1</EmpId>
    <Name>Sam</Name>
    <Sex>Male</Sex>
    <Address>
      <Country>USA</Country>
      <Zip>95220</Zip>
    </Address>
  </Employee>
  <Employee>
    <EmpId>2</EmpId>
    <Name>Lucy</Name>
    <Sex>Female</Sex>
    <Address>
      <Country>USA</Country>
      <Zip>95220</Zip>
    </Address>
  </Employee>
</Employees>

我需要的输出是

<Employees>
  <Employee>
    <EmpId>1</EmpId>
    <Sex>Male</Sex>
    <Address>
     <Zip>95220</Zip>
    </Address>
  </Employee>
  <Employee>
    <EmpId>2</EmpId>
    <Sex>Female</Sex>
    <Address>
      <Zip>95220</Zip>
    </Address>
  </Employee>
</Employees>

我的代码如下。

private void button1_Click(object sender, EventArgs e)
            {
                XmlDocument xDoc = new XmlDocument();

            xDoc.Load(XML_Path);
           // xDoc.Load();
            XmlNodeList xNodes = xDoc.SelectNodes("Employees/Employee");
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            XmlNode employeesNode = doc.CreateElement("Employees");
            doc.AppendChild(employeesNode);
            string s =null;
            string keep = "EmpId,Sex,Address/Zip";
            string[] strArr = keep.Split(',');
            foreach(XmlNode xN in xNodes)
            {
                XmlNode employeeNode = doc.CreateElement("Employee");
                employeesNode.AppendChild(employeeNode);

                foreach (string str in strArr)
                {
                    XmlNode xNod = xN.SelectSingleNode(str);
                    employeeNode.AppendChild(xNod);

                }

            }
            richTextBox1.Text = doc.ToString();

        }

我在内部 foreach 循环中遇到一个奇怪的错误,它不会添加新节点,谁能告诉我我做错了什么。

谢谢

【问题讨论】:

    标签: c# xml linq xml-parsing linq-to-xml


    【解决方案1】:

    使用 Linq to Xml 试试这个,代码会非常简洁。

    private void button1_Click(object sender, EventArgs e)
    {
        var xDoc = XDocument.Load(XML_Path)
        string keep = "EmpId,Sex,Address,Zip";
        string[] strArr = keep.Split(',');
    
        var nodesToDelete = xDoc.Root.Descendants("Employee")
            .SelectMany(e => e.Descendants()
                              .Where(a => !strArr.Contains(a.Name.ToString())));
    
        foreach (var node in nodesToDelete.ToList())
            node.Remove();
    
        richTextBox1.Text = xDoc.ToString();
    }
    

    【讨论】:

    • 谢谢,我正在尝试使这个通用..所以可能会有更多的节点然后名称地址/国家等必须删除.. String Keep 实际上是一个 textBox.Text来自winform,这将定义我需要保留的内容。
    • @user2920743,检查更新的答案,只需将要保留的节点放在不带斜线分隔符的地方
    【解决方案2】:

    你可以这样做:

    XmlDocument source = new XmlDocument();
    source.LoadXml(xmldata);
    
    var keep = new[] {"EmpId", "Sex", "Address/Zip"};
    foreach (XmlElement employee in source.SelectNodes("/Employees/Employee"))
    foreach (XmlElement child in employee.SelectNodes(".//*"))
    {
        if(keep.Any(i => i.StartsWith(child.Name) || i.EndsWith(child.Name)))
            continue;
    
        child.ParentNode.RemoveChild(child);
    }
    Console.WriteLine(source.OuterXml);
    

    但是,由于您的 keep 数组可能会更改并且可能需要不同的场景,您应该尝试使用 XSLT 转换。

    【讨论】:

      【解决方案3】:

      使用 XDocument 怎么样?

      下面的代码为您提供所需的输出。

      string xmlString =
                  @"<?xml version=""1.0""?>
                  <Employees>
                    <Employee>
                      <EmpId>1</EmpId>
                      <Name>Sam</Name>
                      <Sex>Male</Sex>
                      <Address>
                        <Country>USA</Country>
                        <Zip>95220</Zip>
                      </Address>
                    </Employee>
                    <Employee>
                      <EmpId>2</EmpId>
                      <Name>Lucy</Name>
                      <Sex>Female</Sex>
                      <Address>
                        <Country>USA</Country>
                        <Zip>95220</Zip>
                      </Address>
                    </Employee>
                  </Employees>
                  ";
      
              System.Xml.Linq.XDocument xmlDoc = System.Xml.Linq.XDocument.Parse(xmlString);
      
              foreach (var employee in xmlDoc.Descendants("Employee"))
              {
                  employee.Descendants("Name").First().Remove();
      
                  employee.Descendants("Address").First().Descendants("Country").First().Remove();
              }
      
              MessageBox.Show(xmlDoc.ToString());
      

      【讨论】:

      • 谢谢,我正在尝试使这个通用..所以可能会有更多的节点然后名称地址/国家等必须删除.. String Keep 实际上是一个 textBox.Text来自winform,这将定义我需要保留的内容。所以我不确定我必须删除哪些标签,但我知道我必须保留哪些标签..
      • 除了删除之外,还有一种方法可以保留我想要保留的标签?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-10
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多