搜索XML并获取另一个Node

本文关键字:另一个 Node 获取 XML 搜索 | 更新日期: 2023-09-27 18:01:38

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Message>
      <MessageID>1</MessageID>
      <Product>
         <SKU>33333-01</SKU>
      </Product>
   </Message>
</Envelope>

我试过用谷歌搜索,但我不知道我是否只是没有提供正确的搜索条件。

我希望能够基于MessageID搜索XML文件,然后获取SKU。

然后,我想基于SKU搜索另一个XML文件并完全删除该消息。
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Message>
      <MessageID>1</MessageID>
      <Inventory>
         <SKU>33333-01</SKU>
         <Quantity>1</Quantity>
      </Inventory>
   </Message>   
   <Message>
      <MessageID>2</MessageID>
      <Inventory>
         <SKU>22222-01</SKU>
         <Quantity>1</Quantity>
      </Inventory>
   </Message>
</Envelope>

意味着上面的XML变成:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Message>
      <MessageID>2</MessageID>
      <Inventory>
         <SKU>22222-01</SKU>
         <Quantity>1</Quantity>
      </Inventory>
   </Message>
</Envelope>

为了确认,我不能确认MessageID在不同的XML文件上将是相同的。

提前感谢您的帮助。

我的问题:

  1. 如何搜索XML文件?
  2. 我如何获取另一个节点的详细信息
  3. 我可以根据搜索从XML文件中删除完整的内容吗?

搜索XML并获取另一个Node

  1. 您可以使用XmlDocument来加载XML文档。然后,可以使用XPath搜索任何节点。

    XmlDocument document = new XmlDocument();
    document.Load("C:'fileOnTheDisk.xml");
    // or
    document.LoadXml("<a>someXmlString</a>");
    // Returns single element or null if not found    
    var singleNode = document.SelectSingleNode("Envelope/Message[MessageID = '1']"); 
    // Returns a NodeList
    var nodesList = document.SelectNodes("Envelope/Message[MessageID = '1']"); 
    

在w3schools.com阅读更多关于XPath的内容。
这是一个很好的XPath Tester。

  • 例如,可以使用以下XPath根据ID在文档中查找节点:

    XmlDocument document = new XmlDocument();
    document.Load("C:'doc.xml");
    var node = document.SelectSingleNode("Envelope/Message[MessageID = '1']");
    var sku = node.SelectSingleNode("Inventory/SKU").InnerText;
    Console.WriteLine("{0} node has SKU = {1}", 1, sku);
    
  • 或者可以输出所有sku:

        foreach (XmlNode node in document.SelectNodes("Envelope/Message"))
        {
            Console.WriteLine("{0} node has SKU = {1}", 
                node.SelectSingleNode("MessageID").InnerText, 
                node.SelectSingleNode("Inventory/SKU").InnerText);
        }
    

    它将产生:

        1 node has SKU = 33333-01
        2 node has SKU = 22222-01
    

    请注意,如果节点不存在,则可能存在NullReferenceException

  • 您可以简单地使用其父节点的RemoveChild()方法删除它。

    XmlDocument document = new XmlDocument();
    document.Load("C:'doc.xml");
    var node = document.SelectSingleNode("Envelope/Message[MessageID = '1']");
    node.ParentNode.RemoveChild(node);
    document.Save("C:'docNew.xml"); // will be without Message 1
    
  • 您可以使用Linq to XML来做到这一点:

        var doc= XDocument.Load("input.xml");//path of your xml file in which you want to search based on message id.
        var searchNode= doc.Descendants("MessageID").FirstOrDefault(d => d.Value == "1");// It will search message node where its value is 1 and get first of it
         if(searchNode!=null)
         {
            var SKU=searchNode.Parent.Descendants("SKU").FirstOrDefault();
            if(SKU!=null)
            {
               var searchDoc=XDocument.Load("search.xml");//path of xml file where you want to search based on SKU value.
               var nodes =searchDoc.Descendants("SKU").Where(d=>d.Value==SKU.Value).Select(d=>d.Parent.Parent).ToList();
               nodes.ForEach(node=>node.Remove());
               searchDoc.Save("output.xml");//path of output file
            }
        }
    

    我建议您使用LINQ to XML来完成此操作-它比旧的XmlDocument API要好得多。

    对于所有示例,您可以将XML字符串xml解析为XDocument,如下所示:

    var doc = XDocument.Parse(xml);
    

    1。如何搜索XML文件?

    您可以通过查询文档来获取特定消息ID的SKU:

    var sku = (string)doc.Descendants("Message")
        .Where(e => (int)e.Element("MessageID") == 1)
        .SelectMany(e => e.Descendants("SKU"))
        .Single();
    

    2。然后如何获取另一个节点的详细信息?

    您可以使用另一个查询获得具有指定SKU的Message元素:

    var message = doc.Descendants("SKU")
        .Where(sku => (string)sku == "33333-01")
        .SelectMany(e => e.Ancestors("Message"))
        .Single();
    

    3。我可以基于搜索从XML文件中删除一个完整的元素吗?

    使用步骤2的结果,您可以简单地调用Remove:
    message.Remove();
    

    或者,您可以结合步骤2中的查询,并简单地执行命令来删除具有特定SKU的任何消息:

    doc.Descendants("SKU")
        .Where(sku => (string)sku == "33333-01")
        .SelectMany(e => e.Ancestors("Message"))
        .Remove();
    

    我试着回答你所有的问题:

    using System.Xml.XPath;
    using System.Xml.Linq;
    XDocument xdoc1 = XDocument.Load("xml1.xml");
    XDocument xdoc2 = XDocument.Load("xml2.xml");
    string sku = String.Empty;
    string searchedID = "2";
    //1.searching through an xml file based on path
    foreach (XElement message in xdoc1.XPathSelectElements("Envelope/Message"))
    {
        if (message.Element("MessageID").Value.Equals(searchedID))
        {
            //2.grabbing another node's details
            sku = message.XPathSelectElement("Inventory/SKU").Value;
        }
    }
    foreach (XElement message in xdoc2.XPathSelectElements("Envelope/Message"))
    {
        if (message.XPathSelectElement("Inventory/SKU") != null && message.XPathSelectElement("Inventory/SKU").Value.Equals(sku))
        {
            //removing a node
            message.Remove();
        }
    }
    xdoc2.Save("xml2_del.xml");
    }