解析定义了 xmlns 标记但不使用命名空间的 XML 文件

Posted

技术标签:

【中文标题】解析定义了 xmlns 标记但不使用命名空间的 XML 文件【英文标题】:Parsing XML file with xmlns tag defined but not using namespaces 【发布时间】:2021-05-16 08:13:12 【问题描述】:

我正在努力用XPathNavigator 解析XPathDocument,其中XML 文档包含xmlns 标记,但没有使用命名空间前缀。

<?xml version="1.0" encoding="UTF-8"?>
<Order version="1" xmlns="http://example.com">
    <Data>
        <Id>1</Id>
        <b>Aaa</b>
    </Data>
</Order>

SelectSingleNode 方法需要已定义命名空间的命名空间管理器。

XmlNamespaceManager nsmgr = new XmlNamespaceManager(nav.NameTable);
nsmgr.AddNamespace("ns","http://example.com");

因此,我必须在所有 XPath 表达式中开始使用 ns 前缀,尽管原始 XML 文件不使用前缀,例如:

nav.SelectSingleNode("/ns:Order/ns:Data/ns:Id", nsmgr)

这增加了不必要的复杂性。

有什么方法可以推动XPathNavigator 忽略命名空间及其前缀?至少使用前缀,因为命名空间定义本身只存在一次,所以没有太多的努力

【问题讨论】:

我完全同意,我发现的唯一方法是在 localname() 上进行匹配,这与为每个元素都加上命名空间前缀一样丑陋。显然,在 Saxon XPath v3 中,名称空间仅在您指定它们时才匹配,默认情况下匹配 localname()。我希望他们在 XPath 1.0 中考虑到这一点,遗憾的是,在我们坚持使用的 Microsoft C# 世界中,除非您使用 Saxon 或类似的。 【参考方案1】:

XML 有一个默认命名空间。所以每个 XML 元素都绑定到它,可见与否。

最好使用LINQ to XML

它是首选的 XML API,自 2007 年起在 .Net Framework 中可用。

c#

void Main()

    XDocument xdoc = XDocument.Parse(@"<Order version='1' xmlns='http://example.com'>
            <Data>
                <Id>1</Id>
                <b>Aaa</b>
            </Data>
        </Order>");

    XNamespace ns = xdoc.Root.GetDefaultNamespace();

    foreach (XElement elem in xdoc.Descendants(ns + "Data"))
    
        Console.WriteLine("ID: 0, b: 1"
            , elem.Element(ns + "Id")?.Value
            , elem.Element(ns + "b")?.Value);
    

【讨论】:

以上是关于解析定义了 xmlns 标记但不使用命名空间的 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

android xmlns是啥意思

在命名空间定义中使用变量

python 使用xpath解析含有命名空间(xmlns)的xml

命名空间(xmlns属性)

命名空间

php解析带有命名空间的xml