我正在尝试编写一个算法,该算法将XML作为输入,并找到与特定元素相关联的值,但XML体内元素的位置会有所不同。我已经看到许多使用XDocument.Descendants()的例子,但是大多数(如果不是全部)这些例子都希望结构一致,并且后代众所周知。我认为我需要递归XML以找到这个值,但在这样的方式之前,请问普通人群。
当每个调用的元素路径可能不同时,在XDocument中查找元素的最佳方法是什么?只需要找到第一个出现的事件,而不是任何特定的顺序。可以通过走宽或深入发现第一次发生。
例如,如果我试图找到元素“FirstName”,并且Call one的输入XML看起来像..
<?xml version="1.0"?>
<PERSON><Name><FirstName>BOB</FirstName></Name></PERSON>
,下一个电话看起来像:
<?xml version="1.0"?>
<PERSONS><PERSON><Name><FirstName>BOB</FirstName></Name></PERSON></PERSONS>
你推荐什么? XDocument中是否有“查找”选项,我还没有看到过?
上面的简单示例适用于XDocument.Descendents的lazyberezovsky答案,但真正的XML没有。我有问题的XML ......
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:52087/Service1.svc</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/GetDataUsingDataContract</Action>
</s:Header>
<s:Body>
<GetDataUsingDataContract xmlns="http://tempuri.org/">
<composite xmlns:a="http://schemas.datacontract.org/2004/07/WcfService2" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>false</a:BoolValue>
<a:Name>
<a:FirstName>BOB</a:FirstName>
</a:Name>
<a:StringValue i:nil="true" />
</composite>
</GetDataUsingDataContract>
</s:Body>
</s:Envelope>
Search XDocument using LINQ without knowing the namespace
使用以下代码段解决...
var xdoc = XDocument.Parse(xml);
var name = (from p in xdoc.Descendants() where p.Name.LocalName == "FirstName" select p.Value).FirstOrDefault();
答案 0 :(得分:1)
当您使用后代查找第一次出现的元素时,您不需要知道 文件结构。以下代码适用于您的两种情况:
var xdoc = XDocument.Load(path_to_xml);
var name = (string)xdoc.Descendants("FirstName").FirstOrDefault();
与XPath相同
var name = (string)xdoc.XPathSelectElement("//FirstName[1]");
答案 1 :(得分:0)
在不知道XML文档的所有可能排列的情况下(顺便说一下这是非常不寻常的)我认为没有人希望能给你任何有价值的建议。
答案 2 :(得分:0)
“只需要找到第一个匹配项,而不是任何特定的顺序。”我认为Descendants
会欺骗。看看这个:
string xml = @"<?xml version=""1.0""?>
<PERSONS>
<PERSON>
<Name>
<FirstName>BOB</FirstName>
</Name>
</PERSON>
</PERSONS>";
XDocument doc = XDocument.Parse(xml);
Console.WriteLine(string.Join(",", doc.Descendants("FirstName").Select(e =>(string)e)));
xml = @"<?xml version=""1.0""?>
<PERSON>
<Name>
<FirstName>BOB</FirstName>
</Name>
</PERSON>";
doc = XDocument.Parse(xml);
Console.WriteLine(string.Join(",", doc.Descendants("FirstName").Select(e =>(string)e)));