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

时间:2017-12-20 12:22:29

标签: xml vb.net xpath namespaces

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

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

我可以从文档中获取数据,但不能达到我想要的级别。我希望XMLContent节点列表包含“容器”级别的数据。

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

我无法在不先操作XML的情况下将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

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

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

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

也是NS独立的。 Testing link

希望有所帮助。

答案 1 :(得分:0)

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