解析 XDocument,无需继续指定默认命名空间
我有一些 XML 数据(类似于下面的示例),我想读取代码中的值。
为什么我必须指定默认命名空间来访问每个元素?我希望所有元素都使用默认名称空间。
有更合乎逻辑的方法来实现我的目标吗?
示例 XML:
<?xml version="1.0" encoding="UTF-8"?>
<ReceiptsBatch xmlns="http://www.secretsonline.gov.uk/secrets">
<MessageHeader>
<MessageID>00000173</MessageID>
<Timestamp>2009-10-28T16:50:01</Timestamp>
<MessageCheck>BX4f+RmNCVCsT5g</MessageCheck>
</MessageHeader>
<Receipts>
<Receipt>
<Status>OK</Status>
</Receipt>
</Receipts>
</ReceiptsBatch>
我需要的读取 xml 元素的代码:
XDocument xDoc = XDocument.Load( FileInPath );
XNamespace ns = "http://www.secretsonline.gov.uk/secrets";
XElement MessageCheck = xDoc.Element(ns+ "MessageHeader").Element(ns+"MessageCheck");
XElement MessageBody = xDoc.Element("Receipts");
I have some XML data (similar to the sample below) and I want to read the values in code.
Why am I forced to specify the default namespace to access each element? I would have expected the default namespace to be used for all elements.
Is there a more logical way to achieve my goal?
Sample XML:
<?xml version="1.0" encoding="UTF-8"?>
<ReceiptsBatch xmlns="http://www.secretsonline.gov.uk/secrets">
<MessageHeader>
<MessageID>00000173</MessageID>
<Timestamp>2009-10-28T16:50:01</Timestamp>
<MessageCheck>BX4f+RmNCVCsT5g</MessageCheck>
</MessageHeader>
<Receipts>
<Receipt>
<Status>OK</Status>
</Receipt>
</Receipts>
</ReceiptsBatch>
Code to read xml elements I'm after:
XDocument xDoc = XDocument.Load( FileInPath );
XNamespace ns = "http://www.secretsonline.gov.uk/secrets";
XElement MessageCheck = xDoc.Element(ns+ "MessageHeader").Element(ns+"MessageCheck");
XElement MessageBody = xDoc.Element("Receipts");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如此答案所建议的,您可以通过从文档的内存副本中删除所有命名空间来实现此目的。我想只有当您知道生成的文档中不会出现名称冲突时才应该这样做。
As suggested by this answer, you can do this by removing all namespaces from the in-memory copy of the document. I suppose this should only be done if you know you won't have name collisions in the resulting document.
您可以使用 XmlTextReader.Namespaces 属性可在读取 XML 文件时禁用命名空间。
You can use XmlTextReader.Namespaces property to disable namespaces while reading XML file.
这就是 Linq-To-Xml 的工作原理。如果任何元素不在默认命名空间中,则您无法找到任何元素,并且其后代也是如此。摆脱命名空间的最快方法是从初始 XML 中删除指向命名空间的链接。
This is how the Linq-To-Xml works. You can't find any element, if it is not in default namespace, and the same is true about its descendants. The fastest way to get rid from namespace is to remove link to the namespace from your initial XML.
理论上,文档的含义不受用户选择的命名空间前缀的影响。只要数据位于命名空间 http://www.secretsonline.gov.uk/secrets,作者选择使用前缀“s”、“secrets”、“_x.cafe.babe”还是“null”前缀(即使其成为默认命名空间)并不重要。您的应用程序不应该关心:重要的只是 URI。这就是您的应用程序必须指定 URI 的原因。
The theory is that the meaning of the document is not affected by the user's choice of namespace prefixes. So long as the data is in the namespace http://www.secretsonline.gov.uk/secrets, it doesn't matter whether the author chooses to use the prefix "s", "secrets", "_x.cafe.babe", or the "null" prefix (that is, making it the default namespace). Your application shouldn't care: it's only the URI that matters. That's why your application has to specify the URI.
请注意,元素
Receipts
也在命名空间http://www.secretsonline.gov.uk/secrets
中,因此XNamespace
也将是访问元素所需的:作为使用命名空间的替代方法,请注意,您可以使用
local-name()
和namespace-uri()
来使用“命名空间不可知”xpath ,例如如果您省略
namespace-uri
谓词:将匹配
ns1:SomeElement
和ns2:SomeElement
等。IMO 我总是更喜欢XNamespace
在可能的情况下,与命名空间无关的 xpath 的用例非常有限,例如用于解析具有未知模式的文档中的特定元素(例如在服务总线内),或者尽力解析命名空间可以更改的文档(例如未来校对,其中xmlns
发生更改以匹配新版本的文档架构)Note that the element
Receipts
is also in namespacehttp://www.secretsonline.gov.uk/secrets
, so theXNamespace
would also be required for the access to the element:As an alternative to using namespaces note that you can use "namespace agnostic" xpath using
local-name()
andnamespace-uri()
, e.g.If you omit the
namespace-uri
predicate:Would match
ns1:SomeElement
andns2:SomeElement
etc. IMO I would always preferXNamespace
where possible, and the use-cases for namespace-agnostic xpath are quite limited, e.g. for parsing of specific elements in documents with unknown schemas (e.g. within a service bus), or best-effort parsing of documents where the namespace can change (e.g. future proofing, where thexmlns
changes to match a new version of the document schema)