151

私はXDocumentオブジェクトを持っています。LINQ を使用して、任意の深さで特定の名前を持つ要素をクエリしたいと考えています。

を使用するDescendants("element_name")と、現在のレベルの直接の子である要素のみが取得されます。XPath で "//element_name" に相当するものを探しています... を使用する必要がありますXPathか、または LINQ メソッドを使用してそれを行う方法はありますか?

4

10 に答える 10

231

子孫は完全に正常に動作するはずです。次に例を示します。

using System;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        string xml = @"
<root>
  <child id='1'/>
  <child id='2'>
    <grandchild id='3' />
    <grandchild id='4' />
  </child>
</root>";
        XDocument doc = XDocument.Parse(xml);

        foreach (XElement element in doc.Descendants("grandchild"))
        {
            Console.WriteLine(element);
        }
    }
}

結果:

<grandchild id="3" />
<grandchild id="4" />

于 2009-02-19T16:48:20.160 に答える
56

名前空間を示す例:

String TheDocumentContent =
@"
<TheNamespace:root xmlns:TheNamespace = 'http://www.w3.org/2001/XMLSchema' >
   <TheNamespace:GrandParent>
      <TheNamespace:Parent>
         <TheNamespace:Child theName = 'Fred'  />
         <TheNamespace:Child theName = 'Gabi'  />
         <TheNamespace:Child theName = 'George'/>
         <TheNamespace:Child theName = 'Grace' />
         <TheNamespace:Child theName = 'Sam'   />
      </TheNamespace:Parent>
   </TheNamespace:GrandParent>
</TheNamespace:root>
";

XDocument TheDocument = XDocument.Parse( TheDocumentContent );

//Example 1:
var TheElements1 =
from
    AnyElement
in
    TheDocument.Descendants( "{http://www.w3.org/2001/XMLSchema}Child" )
select
    AnyElement;

ResultsTxt.AppendText( TheElements1.Count().ToString() );

//Example 2:
var TheElements2 =
from
    AnyElement
in
    TheDocument.Descendants( "{http://www.w3.org/2001/XMLSchema}Child" )
where
    AnyElement.Attribute( "theName" ).Value.StartsWith( "G" )
select
    AnyElement;

foreach ( XElement CurrentElement in TheElements2 )
{
    ResultsTxt.AppendText( "\r\n" + CurrentElement.Attribute( "theName" ).Value );
}
于 2009-06-23T15:07:19.523 に答える
48

あなたはこのようにそれを行うことができます:

xml.Descendants().Where(p => p.Name.LocalName == "Name of the node to find")

はどこにxmlありますかXDocument

プロパティは、とNameを含むオブジェクトを返すことに注意してください。そのため、名前で比較する場合はを使用する必要があります。LocalNameNamespaceName.LocalName

于 2013-01-21T12:14:51.627 に答える
13

これを実現するには 2 つの方法があります。

  1. XML へのリンク
  2. XPath

以下は、これらのアプローチの使用例です。

List<XElement> result = doc.Root.Element("emails").Elements("emailAddress").ToList();

XPath を使用する場合は、IEnumerable でいくつかの操作を行う必要があります。

IEnumerable<XElement> mails = ((IEnumerable)doc.XPathEvaluate("/emails/emailAddress")).Cast<XElement>();

ご了承ください

var res = doc.XPathEvaluate("/emails/emailAddress");

NULL ポインタが返されるか、結果が返されません。

于 2012-05-03T11:27:11.073 に答える
8

XPathSelectElementsメソッドと同じように機能する拡張メソッドを使用していXmlDocument.SelectNodesます:

using System;
using System.Xml.Linq;
using System.Xml.XPath; // for XPathSelectElements

namespace testconsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xdoc = XDocument.Parse(
                @"<root>
                    <child>
                        <name>john</name>
                    </child>
                    <child>
                        <name>fred</name>
                    </child>
                    <child>
                        <name>mark</name>
                    </child>
                 </root>");

            foreach (var childElem in xdoc.XPathSelectElements("//child"))
            {
                string childName = childElem.Element("name").Value;
                Console.WriteLine(childName);
            }
        }
    }
}
于 2013-02-08T14:52:00.703 に答える
0

上記が真実であることはわかっています。ジョンは決して間違っていません。現実の願いはもう少し先に進むことができます。

<ota:OTA_AirAvailRQ
    xmlns:ota="http://www.opentravel.org/OTA/2003/05" EchoToken="740" Target=" Test" TimeStamp="2012-07-19T14:42:55.198Z" Version="1.1">
    <ota:OriginDestinationInformation>
        <ota:DepartureDateTime>2012-07-20T00:00:00Z</ota:DepartureDateTime>
    </ota:OriginDestinationInformation>
</ota:OTA_AirAvailRQ>

たとえば、通常、問題は、上記の XML ドキュメントで EchoToken を取得するにはどうすればよいかということです。または name 属性で要素をぼかす方法。

  1. 以下のように名前空間と名前でアクセスすることでそれらを見つけることができます

     doc.Descendants().Where(p => p.Name.LocalName == "OTA_AirAvailRQ").Attributes("EchoToken").FirstOrDefault().Value
    
  2. このようなコンテンツの属性値で見つけることができます。

于 2019-07-24T10:50:53.657 に答える
-1

(コードと手順は C# 用であり、他の言語では若干変更する必要がある場合があります)

この例は、多くの子を持つ親ノードから読み取りたい場合に最適です。たとえば、次の XML を見てください。

<?xml version="1.0" encoding="UTF-8"?> 
<emails>
    <emailAddress>jdoe@set.ca</emailAddress>
    <emailAddress>jsmith@hit.ca</emailAddress>
    <emailAddress>rgreen@set_ig.ca</emailAddress> 
</emails>

次に、以下のコードを使用します (XML ファイルはリソースに保存されることに注意してください (リソースに関するヘルプについては、スニペットの最後にあるリンクを参照してください))。「emails」タグ内で各電子メール アドレスを取得できます。

XDocument doc = XDocument.Parse(Properties.Resources.EmailAddresses);

var emailAddresses = (from emails in doc.Descendants("emailAddress")
                      select emails.Value);

foreach (var email in emailAddresses)
{
    //Comment out if using WPF or Windows Form project
    Console.WriteLine(email.ToString());

   //Remove comment if using WPF or Windows Form project
   //MessageBox.Show(email.ToString());
}

結果

  1. jdoe@set.ca
  2. jsmith@hit.ca
  3. rgreen@set_ig.ca

注: コンソール アプリケーションと WPF または Windows フォームの場合は、「using System.Xml.Linq;」を追加する必要があります。プロジェクトの上部にある Using ディレクティブ。Console の場合、Using ディレクティブを追加する前に、この名前空間への参照も追加する必要があります。また、コンソールの場合、デフォルトでは「Properties フォルダ」の下にリソース ファイルがないため、リソース ファイルを手動で追加する必要があります。以下の MSDN の記事では、これについて詳しく説明しています。

リソースの追加と編集

方法: リソースを追加または削除する

于 2011-11-18T11:36:57.743 に答える