为什么在解析XML时需要使用XmlNamespaceManager?

3
当我使用selectSingleNode获取null值时,我发现需要声明一个命名空间,因为我使用了xmlns属性。我的问题是,如果在xml文件本身中未使用前缀,为什么在解析xml时需要使用前缀?
我使用xmlns属性的原因是,我的xml输出的接收端要求它。我宁愿从基本的xml文件中读取它,而不是在程序中硬编码它。
以下是可行的代码。
xmlns = New XmlNamespaceManager(xmlTemplate.NameTable)
xmlns.AddNamespace("dc", ns)

我尝试过这样做-不起作用

xmlns = New XmlNamespaceManager(xmlTemplate.NameTable)
xmlns.AddNamespace(String.Empty, ns)

简言之,有没有什么方法可以去除“dc”前缀?

你正在解析的XML长什么样? - Jon
以下,克里斯的假设是正确的。归结为类似于“<xml xmlns="http://www.exmaple.com/"><node/></xml>”这样的东西。 - Phil
2个回答

4
这只是一个“按照他们构建的方式”的问题。根据 MSDN(具有命名空间映射前缀的XPath查询)
XmlNamespaceManager允许使用空字符串作为前缀添加默认命名空间。但是,XPath将空前缀视为null命名空间。换句话说,在XPath查询中只能使用映射到命名空间的前缀。如果要在XPath表达式中使用XML文档中的默认命名空间,则需要为其定义前缀。
还从 MSDN(XmlNamespaceManager.AddNamespace)中得知:
如果XmlNamespaceManager将用于解析XML路径语言(XPath)表达式中的命名空间,则必须指定前缀。如果XPath表达式不包含前缀,则假定命名空间统一资源标识符(URI)为空命名空间

我假设你的代码类似于:

Dim S = "<xml xmlns=""http://www.exmaple.com/""><node/></xml>"

Dim X As New Xml.XmlDocument()

X.LoadXml(S)
Dim NS As New Xml.XmlNamespaceManager(X.NameTable)
NS.AddNamespace("dc", "http://www.exmaple.com/")

''//Will not work
Dim N1 = X.SelectSingleNode("//xml/node", NS)
If N1 Is Nothing Then
    Trace.WriteLine("Node not found")
Else
    Trace.WriteLine("Node found")
End If

''//Works
Dim N2 = X.SelectSingleNode("//dc:xml/dc:node", NS)
If N2 Is Nothing Then
    Trace.WriteLine("Node not found")
Else
    Trace.WriteLine("Node found")
End If

好的,那么理想情况是接收方只需读取xml并在需要的时候添加名称空间,这样我就不必将所有内容都加上硬编码的“dc:”前缀了。 如果是这种情况,那我就满意了。 另外,您对我的代码做出的假设完全正确。 - Phil
你需要在那里使用命名空间吗?你能把它移除掉吗? - Chris Haas
我会尝试更好地解释:我有一个XML文件,我读取它->添加到内容中->将其转发给另一个接收它的进程。我想让xmlns在xml中预先存在,而不是在代码中硬编码。原因是,如果这个“模板”中的任何内容发生变化,不应该在代码中进行更改。但似乎接收XML的进程(依赖于xmlns)应该添加命名空间,而不是我。 - Phil

2

您应该能够通过以下方式从传入的XML中获取命名空间,而不必硬编码:

NS.AddNamespace("dc",X.DocumentElement.Attributes("xmlns").InnerText)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接