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

要素の最初の出現を見つけるために子孫を使用している場合、ファイルの構造を知る必要はありません。次のコードは、両方のケースで機能します。

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

「特定の順序ではなく、最初に見つかったものだけが必要です。」私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 に答える