从XML中选择节点并创建新的XML

时间:2013-10-27 22:33:58

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

我试图剥离我的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循环中得到一个奇怪的错误它不会添加新节点任何人都可以告诉我我做错了什么。

由于

3 个答案:

答案 0 :(得分:0)

尝试使用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();
}

答案 1 :(得分:0)

如何使用XDocument?

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

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());

答案 2 :(得分:0)

你可以选择这样的东西:

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转换。