我有一些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");
答案 0 :(得分:6)
根据this answer的建议,您可以通过从文档的内存中副本中删除所有名称空间来完成此操作。我想这应该只在您知道结果文档中没有名称冲突时才能完成。
/// <summary>
/// Makes parsing easier by removing the need to specify namespaces for every element.
/// </summary>
private static void RemoveNamespaces(XDocument document)
{
var elements = document.Descendants();
elements.Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
foreach (var element in elements)
{
element.Name = element.Name.LocalName;
var strippedAttributes =
from originalAttribute in element.Attributes().ToArray()
select (object)new XAttribute(originalAttribute.Name.LocalName, originalAttribute.Value);
//Note that this also strips the attributes' line number information
element.ReplaceAttributes(strippedAttributes.ToArray());
}
}
答案 1 :(得分:4)
您可以在读取XML文件时使用XmlTextReader.Namespaces属性来禁用命名空间。
string filePath;
XmlTextReader xReader = new XmlTextReader(filePath);
xReader.Namespaces = false;
XDocument xDoc = XDocument.Load(xReader);
答案 2 :(得分:2)
这就是Linq-To-Xml的工作原理。如果它不在默认命名空间中,则找不到任何元素,并且它的后代也是如此。摆脱命名空间的最快方法是从初始XML中删除指向命名空间的链接。
答案 3 :(得分:1)
请注意,元素Receipts
也位于命名空间http://www.secretsonline.gov.uk/secrets
中,因此访问元素时也需要XNamespace
:
XElement MessageBody = xDoc.Element(ns + "Receipts");
作为使用命名空间的替代方法,请注意您可以使用local-name()
和namespace-uri()
使用“命名空间无关”xpath,例如
/*[local-name()='SomeElement' and namespace-uri()='somexmlns']
如果省略namespace-uri
谓词:
/*[local-name()='SomeElement']
匹配ns1:SomeElement
和ns2:SomeElement
等IMO我总是更喜欢XNamespace
,而名称空间无关的xpath的用例非常有限,例如用于解析具有未知模式的文档中的特定元素(例如,在服务总线内),或尽力解析命名空间可以更改的文档(例如,未来校对,xmlns
更改以匹配新版本的文件架构)
答案 4 :(得分:1)
理论上,文档的含义不受用户选择的名称空间前缀的影响。只要数据在命名空间http://www.secretsonline.gov.uk/secrets中,作者是否选择使用前缀“s”,“secrets”,“_ x.cafe.babe”或“null”前缀并不重要(即,使其成为默认命名空间)。您的应用程序不应该关心:它只是重要的URI。这就是您的应用程序必须指定URI的原因。