搜索XML并抓取另一个节点

时间:2015-07-08 09:30:32

标签: c# xml search

<?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文件中删除完整内容吗?

4 个答案:

答案 0 :(得分:0)

  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']"); 
    
  2. Read more about XPath at w3schools.com
    这是一个很好的XPath Tester

    1. 例如,您可以使用以下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);
      
    2. 或者您可以输出所有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

      1. 您只需使用其父级的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
        

答案 1 :(得分:0)

您可以使用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
        }
    }

答案 2 :(得分:0)

我建议你使用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();

答案 3 :(得分:0)

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

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");
}