回答:
子孫は完全に問題なく動作するはずです。次に例を示します。
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" />
doc.Descendants("Cars").Descendants("Part")
可能性(または.Elements("Part")
。彼らは唯一の直接の子だったら
var foo = new XDocument().Descendants("Bar").Descendants("Baz");
のでDescendants
リターンは空にIEnumerable<XElement>
していませんnull
。
名前空間を示す例:
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 );
}
あなたはこの方法でそれを行うことができます:
xml.Descendants().Where(p => p.Name.LocalName == "Name of the node to find")
どこxml
ですXDocument
。
プロパティName
はa LocalName
とa を持つオブジェクトを返すことに注意してくださいNamespace
。そのName.LocalName
ため、名前で比較する場合に使用する必要があります。
子孫はあなたが必要とするものを正確に行いますが、要素の名前と一緒に名前空間名を含めたことを確認してください。省略した場合、空のリストが表示される可能性があります。
これを行うには2つの方法があります。
以下は、これらのアプローチの使用例です。
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ポインタか、結果がありません。
XPathEvaluate
はSystem.Xml.XPath
名前空間にあることに言及するだけです。
私は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);
}
}
}
}
@Francisco Goldensteinの回答に続いて、拡張メソッドを作成しました
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Mediatel.Framework
{
public static class XDocumentHelper
{
public static IEnumerable<XElement> DescendantElements(this XDocument xDocument, string nodeName)
{
return xDocument.Descendants().Where(p => p.Name.LocalName == nodeName);
}
}
}
上記が正しいことを知っています。ジョンは決して間違いではありません。実生活の願いはもう少し先に行くことができます
<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を取得するにはどうすればよいですか?または、attrbuteという名前の要素をぼかす方法。
1-以下のような名前空間と名前でアクセスすることでそれらを見つけることができます
doc.Descendants().Where(p => p.Name.LocalName == "OTA_AirAvailRQ").Attributes("EchoToken").FirstOrDefault().Value
2- このように、属性の内容の値によってそれを見つけることができます
これLinq
は、XDocument
クラスの子孫メソッドに基づくソリューションの私のバリアントです
using System;
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
XDocument xml = XDocument.Parse(@"
<root>
<child id='1'/>
<child id='2'>
<subChild id='3'>
<extChild id='5' />
<extChild id='6' />
</subChild>
<subChild id='4'>
<extChild id='7' />
</subChild>
</child>
</root>");
xml.Descendants().Where(p => p.Name.LocalName == "extChild")
.ToList()
.ForEach(e => Console.WriteLine(e));
Console.ReadLine();
}
}
(コードと手順は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());
}
注:コンソールアプリケーションおよびWPFまたはWindowsフォームの場合、「using System.Xml.Linq;」を追加する必要があります。プロジェクトの上部にあるUsingディレクティブ。Consoleの場合、Usingディレクティブを追加する前に、このネームスペースへの参照を追加する必要があります。また、コンソールの場合、デフォルトでは「プロパティフォルダー」の下にリソースファイルがないため、手動でリソースファイルを追加する必要があります。以下のMSDNの記事で、これについて詳しく説明しています。