无法使用XmlDocument.select节点选择节点

时间:2018-01-06 09:30:09

标签: node.js xml vb.net xpath

我尝试使用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.我认为它找不到节点&#34; Defect_details_linenumber&#34;。你能帮我指一下xPath&#34; descendant :: fields [field / fieldname =&#39; Defect_detailsAf_artefs&#39;]&#34;或代码中的错误

我试过xpath&#34;&#34; descendant :: fields&#34;但我得到了同样的问题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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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)