1

我正在尝试编写一个将 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>

更新:

lazyberezovsky 极大地帮助我向我展示了 Descendents 应该如何工作。注意 XML 中的名称空间。学过的知识。又发现了一个。有类似问题的文章..

在不知道命名空间的情况下使用 LINQ 搜索 XDocument

使用以下代码段解决...

var xdoc = XDocument.Parse(xml);
var name = (from p in xdoc.Descendants() where p.Name.LocalName == "FirstName" select p.Value).FirstOrDefault();
4

3 回答 3

1

当您使用 Descendants 查找第一次出现的元素时,您不需要知道文件的结构。以下代码适用于您的两种情况:

var xdoc = XDocument.Load(path_to_xml);
var name = (string)xdoc.Descendants("FirstName").FirstOrDefault();

与 XPath 相同

var name = (string)xdoc.XPathSelectElement("//FirstName[1]");
于 2013-02-17T22:18:09.820 回答
0

在不了解 XML 文档的所有可能排列方式的情况下(顺便说一句,这很不寻常),我认为没有人希望给您任何有价值的建议。

于 2013-02-17T22:06:30.180 回答
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)));
于 2013-02-17T22:18:17.953 回答