搜索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文件上将是相同的。
提前感谢您的帮助。
我的问题:
- 如何搜索XML文件?
- 我如何获取另一个节点的详细信息
- 我可以根据搜索从XML文件中删除完整的内容吗?
-
您可以使用
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);
您可以简单地使用其父节点的
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
或者可以输出所有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
。
您可以使用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");
}