如何获取带有命名空间的 XML 元素

Đức*_*Bùi 1 c# xml linq-to-xml xml-namespaces

我有一个像这样的 XML 文件:

\n\n

我想获取所有标签 a:entry

\n\n
<?xml version="1.0" encoding="utf-8"?>\n<a:feed xmlns:a="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://schemas.zune.net/catalog/apps/2008/02">\n  <a:link rel="next" type="application/atom+xml" href="/v8/catalog/apps?q=facebook&amp;startIndex=50&amp;chunkSize=50&amp;pagingToken=50%7c50&amp;os=8.0.10512.0&amp;cc=US&amp;oc=&amp;lang=vi-VN&amp;hw=469838850&amp;dm=Virtual&amp;oemId=NOKIA&amp;moId=" />\n  <a:link rel="self" type="application/atom+xml" href="/v8/catalog/apps?q=facebook&amp;chunkSize=50&amp;os=8.0.10512.0&amp;cc=US&amp;oc=&amp;lang=vi-VN&amp;hw=469838850&amp;dm=Virtual&amp;oemId=NOKIA&amp;moId=" />\n  <os:startIndex>0</os:startIndex>\n  <os:totalResults>51</os:totalResults>\n  <os:itemsPerPage>50</os:itemsPerPage>\n  <a:updated>2013-11-01T08:30:11.711450Z</a:updated>\n  <a:title type="text">List Of Items</a:title>\n  <a:id>tag:catalog.zune.net,2013-11-01:/apps</a:id>\n  <pagingToken>50|50</pagingToken>\n  <impressionId>cd11c7b0116143dcb4c99f15b72ebbc4</impressionId>\n  <a:entry>\n    <a:updated>2013-11-01T08:30:11.711450Z</a:updated>\n    <a:title type="text">Facebook</a:title>\n    <a:id>urn:uuid:82a23635-5bd9-df11-a844-00237de2db9e</a:id>\n    <isHardwareCompatible>true</isHardwareCompatible>\n    <sortTitle>Facebook</sortTitle>\n    <releaseDate>2010-10-19T13:07:17.103000Z</releaseDate>\n    <version>5.1.2.0</version>\n    <averageUserRating>5.963479</averageUserRating>\n    <userRatingCount>42825</userRatingCount>\n    <image>\n      <id>urn:uuid:f8b42bcd-45c3-4ea5-9c9e-a108ac33cd6e</id>\n    </image>\n    <hasLiveTile>true</hasLiveTile>\n    <categories>\n      <category>\n        <id>windowsphone.Social</id>\n        <title>ma\xcc\xa3ng xa\xcc\x83 h\xc3\xb4\xcc\xa3i</title>\n        <isRoot>True</isRoot>\n      </category>\n    </categories>\n    <tags>\n      <tag>Independent</tag>\n      <tag>LockScreen_Background</tag>\n      <tag>LockScreen_Notification_IconCount</tag>\n      <tag>LockScreen_Notification_TextField</tag>\n      <tag>phone.protocol.fb</tag>\n    </tags>\n    <offers>\n      <offer>\n        <offerId>urn:uuid:5c6b4028-74c5-4648-a71e-2ca413a5d2fd</offerId>\n        <mediaInstanceId>urn:uuid:64051c69-fb7b-4972-ad42-1dbb2e626a2c</mediaInstanceId>\n        <clientTypes>\n          <clientType>WindowsPhone80</clientType>\n          <clientType>WindowsPhone81</clientType>\n        </clientTypes>\n        <paymentTypes>\n          <paymentType>Credit Card</paymentType>\n          <paymentType>Mobile Operator</paymentType>\n        </paymentTypes>\n        <store>ZEST</store>\n        <price>0</price>\n        <displayPrice>$0.00</displayPrice>\n        <priceCurrencyCode>USD</priceCurrencyCode>\n        <licenseRight>Purchase</licenseRight>\n      </offer>\n    </offers>\n    <publisher>\n      <id>Microsoft Corporation</id>\n      <name>Microsoft Corporation</name>\n    </publisher>\n    <impressionId>cd11c7b0116143dcb4c99f15b72ebbc4</impressionId>\n    <k>4</k>\n  </a:entry>\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的代码:

\n\n
  var list = from r in xdoc.Descendants("a:entry") select r;\n
Run Code Online (Sandbox Code Playgroud)\n\n

我收到这个错误:

\n\n
\n

名称中不能包含 \':\' 字符(十六进制值 0x3A)。\n

\n
\n\n

我如何获得 a:entry 标签?谢谢 :)

\n

Ily*_*nov 6

您需要指定XNamespace:

XNamespace xmlns = "http://www.w3.org/2005/Atom";
Run Code Online (Sandbox Code Playgroud)

然后使用接受字符串的XNamespace重载+运算符:

var list = from r in xdoc.Descendants(xmlns + "entry") select r;
Run Code Online (Sandbox Code Playgroud)

甚至更好

var list = xdoc.Descendants(xmlns + "entry");
Run Code Online (Sandbox Code Playgroud)

例如,要从 First 中选择所有标签,entry请使用下一个代码作为示例:

XNamespace entryNamespace = "http://www.w3.org/2005/Atom";
XNamespace tagNamespace = "http://schemas.zune.net/catalog/apps/2008/02";

var tags = xdoc.Descendants(entryNamespace + "entry")
               .First()
               .Descendants(tagNamespace + "tag");

foreach (var tag in tags)
{
    Console.WriteLine (tag.Value);
}
Run Code Online (Sandbox Code Playgroud)

印刷:

Independent
LockScreen_Background
LockScreen_Notification_IconCount
LockScreen_Notification_TextField
phone.protocol.fb
Run Code Online (Sandbox Code Playgroud)

这是与名称空间无关的版本(选择相同的tags):

var tags = xdoc.Descendants()
               .Where(node => node.Name.LocalName == "entry")
               .First()
               .Descendants()
               .Where(node => node.Name.LocalName == "tag");
Run Code Online (Sandbox Code Playgroud)

当然,您始终可以选择 xml 中的所有标签,而无需指定命名空间或entry节点名称:

var tags = xdoc.Descendants()
               .Where(node => node.Name.LocalName == "tag");
Run Code Online (Sandbox Code Playgroud)