【问题标题】:Can't select node with XmlDocument.select node无法使用 XmlDocument.select 节点选择节点
【发布时间】:2018-01-06 09:30:08
【问题描述】:

我尝试使用 XmlDocument.select 在下面的 xml 文件中获取节点的值

<?xml version="1.0"?>
<cqresponse xmlns="http://ibm.com/rational/clearquest/web/v7.1">
  <displayname>hello world</displayname>
  <fields>
    <field>
      <fieldname>Defect_details_linenumber</fieldname>
      <datatype>MULTILINE_STRING</datatype>
      <value><![CDATA[["aaa"]]]></value>
    </field>
    <field>
      <fieldname>Defect_detailsAf_artefs</fieldname>
      <datatype>MULTILINE_STRING</datatype>
      <value><![CDATA[["bbb"]]]></value>
    </field>
  </fields>
</cqresponse>

使用此代码

Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click     
    Dim doc As XmlDocument = New XmlDocument()
    doc.Load("Temp_File.xml")
    Dim nodeList As XmlNodeList
    Dim root As XmlNode = doc.DocumentElement
    nodeList = root.SelectNodes("descendant::fields[field/fieldname='Defect_detailsAf_artefs']")

    Debug.Print(nodeList.Count)
    Debug.Print(nodeList(0).InnerText)
End Sub

但 nodelist.count 总是返回 0。我认为它找不到节点“Defect_details_linenumber”。您能否帮我指出 xPath "descendant::fields[field/fieldname='Defect_detailsAf_artefs']" 中是否有问题或代码中有问题

我尝试使用 xpath ""descendant::fields" 但我遇到了同样的问题 nodelist.count 仍然返回 0

已解决

无法选择节点,因为它缺少命名空间。如果我们改为这样,我的代码会很好

Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click     
    Dim doc As XmlDocument = New XmlDocument()
    doc.Load("Temp_File.xml")

    'Add namespace for xml here
    Dim ns As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable)
    ns.AddNamespace("ibm", "http://ibm.com/rational/clearquest/web/v7.1")

    'Get root node: node "cqresponse"
    Dim root As XmlNode = doc.DocumentElement
    'Get node which have child node fieldname = 'Defect_details_linenumber'
    Dim node As XmlNode = root.SelectSingleNode("descendant::ibm:fields/ibm:field[ibm:fieldname='Defect_detailsAf_artefs']/ibm:value", ns)

    Debug.Print(node.InnerText) 'it will show "bbb"

End Sub

【问题讨论】:

    标签: node.js xml vb.net xpath


    【解决方案1】:

    这是因为 XML 在根目录中声明了 默认命名空间。这意味着该 XML 文档中所有没有前缀的元素都在命名空间 http://ibm.com/rational/clearquest/web/v7.1 中。为了能够使用 XPath 选择命名空间中的元素,您需要定义一个引用该命名空间的前缀,并修改 XPath 以使用该前缀,例如:

    ....
    Dim nsManager As New XmlNamespaceManager(New NameTable())
    nsManager.AddNamespace("d", "http://ibm.com/rational/clearquest/web/v7.1")
    nodeList = root.SelectNodes("//d:fields[d:field/d:fieldname='Defect_detailsAf_artefs']", nsManager)
    

    【讨论】:

    • 嗨 har07,我刚刚找到了与您的答案相同的解决方案 =)) 但是,您的问题正是如此,它需要一个命名空间来选择。我会投票给这个答案。谢谢你的帮助:)
    【解决方案2】:
    Imports <xmlns="http://ibm.com/rational/clearquest/web/v7.1">
    
    Sub Test()
        Dim xml =
            <?xml version="1.0"?>
            <cqresponse xmlns="http://ibm.com/rational/clearquest/web/v7.1">
                <displayname>hello world</displayname>
                <fields>
                    <field>
                        <fieldname>Defect_details_linenumber</fieldname>
                        <datatype>MULTILINE_STRING</datatype>
                        <value><![CDATA[["aaa"]]]></value>
                    </field>
                    <field>
                        <fieldname>Defect_detailsAf_artefs</fieldname>
                        <datatype>MULTILINE_STRING</datatype>
                        <value><![CDATA[["bbb"]]]></value>
                    </field>
                </fields>
            </cqresponse>
    
        Dim fields = xml...<field>.Where(Function(f) f.<fieldname>.Value = "Defect_detailsAf_artefs")
        fields.ToList().ForEach(Sub(f) Console.WriteLine(f.ToString()))
    End Sub
    

    【讨论】:

    • 嗨 JohnyL,xml 是否... 可以替换为 Dim doc As XmlDocument = New XmlDocument()?
    • 我只是想问更多关于这种方式是否比选择节点更好?为什么我不能使用选择节点来查找节点?
    • @Bruce 您只是在使用另一组操作 XML 的对象。我正在使用 System.Xml.Linq 中的XElement(更具体地说,XDocument)。此外,我在这里使用了一个仅存在于 VB.NET 中的独特功能 - XML Literals。三个点... 表示选择具有定义名称的每个元素,无论它有多深。
    • 嗨,约翰,我终于找到了解决方案,非常感谢您的回答,非常感谢您的帮助
    • @Bruce 这是另一种解决方案吗?如果是,请回复您的答案并在此处发布您的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多