读取具有多个名称空间的子节点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读取具有多个名称空间的子节点相关的知识,希望对你有一定的参考价值。

关于命名空间和读取XML节点的帖子很多,但我一直无法找到特定查询的答案。我相信我的方法是正确的,但我显然错过了阻止它工作的东西。

概述 - 我正在进行Web服务调用,它返回XML,我需要清理并动态创建和填充数据表。要清理我正在尝试从包含多个名称空间的返回XML中读取我需要的节点。

我可以从文档中获取数据,但不能达到我想要的级别。我希望XML Content nodelist包含“Container”级别的数据。

代码中的注释显示的是给出数据但不是所需级别的行以及我期望返回下一级别的行,但它不会返回任何内容。我很欣赏得到我需要的东西,我需要降低另一个级别,但这是nodelist返回null的点。

我不能只是在没有先操作它的情况下将XML加载到数据集或数据表中。

示例XML

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="namespaceone" xmlns:xsi="namespacetwo" xmlns:xsd="namespacethree">
    <soap:Body>
        <Response xmlns="http://namespacefour">
            <Result>
                <Data xmlns="http://namespacefive" xmlns:t="http://namespacesix">
                    <Container>
                        <Properties>
                            <Property1>a</Property1>
                            <Property2>b</Property2>
                        </Properties>
                    </Container>
                    <Container>
                        <Properties>
                            <Property1>c</Property1>
                            <Property2>d</Property2>
                        </Properties>
                    </Container>
                </Data>
            </Result>
        </Response>
    </soap:Body>
</soap:Envelope>
        Dim XMLdoc As XmlDocument = New XmlDocument()
        XMLdoc.LoadXml(strXML)

        Dim XMLContent As XmlNodeList

        Dim nsMgr As New XmlNamespaceManager(XMLdoc.NameTable())
        ns.AddNamespace("dflt", XMLdoc.DocumentElement.NamespaceURI)
        ns.AddNamespace("ns1", XMLdoc.DocumentElement.GetNamespaceOfPrefix("soap"))
        ns.AddNamespace("ns2", "http://namespacetwo")
        ns.AddNamespace("ns3", "http://namespacethree")
        ns.AddNamespace("ns4", "http://namespacefour")
        ns.AddNamespace("ns5", "http://namespacefive")
        ns.AddNamespace("ns6", "http://namespacesix")

        'This returns content but not at the level I want
        XMLContent = XMLdoc.SelectNodes("/ns1:Envelope/ns1:Body/ns4:Response/ns4:Result", nsMgr)

        'This does not return anything
        XMLContent = XMLdoc.SelectNodes("/ns1:Envelope/ns1:Body/ns4:Response/ns4:Result/ns5:Data", nsMgr)

        If Not XMLContent Is Nothing Then
            For Each node As XmlNode In XMLContent
                'Create and populate table here
            Next node
        End If

感谢您的帮助。

答案

不是最优雅的方式,但会起作用:

//*[local-name(.) = 'Response']/*[local-name(.) = 'Result']/*[local-name(.) = 'Data']

也是NS独立的。 Testing link

希望有所帮助。

另一答案

谢谢你的建议,但我已经解决了。事实证明,XML是从数据节点和下面编码的,尽管外部节点没有编码。我本应该发现这一点,但没想到编码的混合而不是。无论如何,如果我在Web服务输出上运行HttpUtility.htmlDecode,那么我最初发布的代码工作正常。

以上是关于读取具有多个名称空间的子节点的主要内容,如果未能解决你的问题,请参考以下文章

使用 xpath 访问具有命名空间的子节点

如何使用 XPath 忽略命名空间

需要使用具有相同名称的子节点迭代 xml

如何获取具有相同名称的元素并根据 XSLT 中的子节点值对它们进行排序

Firebase如何添加具有给定名称的子节点?

XPathExpression 选择忽略命名空间的子属性值