XML子节点显示在他们不属于的父节点下

时间:2015-03-10 19:19:27

标签: xml vb.net

我在VB中尝试解析XML文件时遇到了一些奇怪的结果。我正在尝试为每个显示解析一个标签列表(前面带有“ - ”)。相反,每个显示部分都列出了XML文件中的整个标签列表,而不仅仅是分配给显示器的标签。

这就是我想要的:

C1_L2_4FRAC
--04PC6016
--04PC6016TQ
C1_L2_4TOPPER
--04PC6400
--04PC6400TQ

这就是我得到的:

C1_L2_4FRAC
--04PC6016
--04PC6016TQ
--04PC6400
--04PC6400TQ
C1_L2_4TOPPER
--04PC6016
--04PC6016TQ
--04PC6400
--04PC6400TQ

以下是XML示例:

<?xml version="1.0" encoding="utf-16le"?>
<DisplaysCfg>
<DISPLAY NAME="C1_L2_4FRAC">
  <SYMBOL NAME="PG_ALARMSYMBOL_X2">
    <POSITION X="180" Y="173"/>
    <ACTION NAME="Load Page" PARAM="PG_ALARMLIST_x2,T=04PC6016,T=04PC6016TQ"/>
    <TAG NAME="04PC6016" INDEX="566" DATA_PROC="Infinet.DCS"/>
    <TAG NAME="04PC6016TQ" INDEX="567" DATA_PROC="Infinet.DOL"/>
    <PARAMS DTLS=" GHOSTCLICKPT = FALSE"/>
  </SYMBOL>
</DISPLAY>
<DISPLAY NAME="C1_L2_4TOPPER">
  <SYMBOL NAME="PG_ALARMSYMBOL_X2">
    <POSITION X="1410" Y="154"/>
    <ACTION NAME="Load Page" PARAM="PG_ALARMLIST_x2,T=04PC6400,T=04PC6400TQ"/>
    <TAG NAME="04PC6400" INDEX="583" DATA_PROC="Infinet.DCS"/>
    <TAG NAME="04PC6400TQ" INDEX="584" DATA_PROC="Infinet.DOL"/>
    <PARAMS DTLS=" GHOSTCLICKPT = FALSE"/>
  </SYMBOL>
</DISPLAY>
</DisplaysCfg>

这是有问题的代码:

For Each displaynode In xmldoc.SelectNodes("/DisplaysCfg")
            Dim screenname As String = ""
            For Each attrib As XmlElement In displaynode
                screenname = attrib.GetAttribute("NAME")
                Debug.Print(screenname)
                For Each symbolnode In displaynode.SelectNodes("./DISPLAY/SYMBOL")
                    For Each tagattrib As XmlElement In symbolnode
                        If tagattrib.Name = "TAG" Then
                            Debug.Print("--" & tagattrib.GetAttribute("NAME"))
                        End If
                    Next
                Next
            Next
        Next

关于我做错了什么的线索?

2 个答案:

答案 0 :(得分:0)

以前从未这样做过,但经过一点阅读后,这可能就是你想要的:

For Each displaynode In xmldoc.SelectNodes("/DisplaysCfg")
            Dim screenname As String = ""
            For Each Attrib As XmlElement In displaynode
                Debug.print(Attrib.GetAttribute("NAME"))
            Next
            For Each symbolnode In displaynode.ChildNodes
                For Each tagattrib As XmlElement In symbolnode
                    If tagattrib.Name = "TAG" Then
                        Debug.Print("--" & tagattrib.GetAttribute("NAME"))
                    End If
                Next
            Next
        Next

http://www.java2s.com/Code/VB/XML/GetElementsByTagNameandLoopthroughNodes.htm

看起来你只是从根目录而不是从displaynode内部选择节点,导致它忽略它并运行两次。

答案 1 :(得分:0)

这是因为对于每个<DISPLAY>元素,您都在遍历所有 <SYMBOL>元素:

For Each symbolnode In displaynode.SelectNodes("./DISPLAY/SYMBOL")

请注意,上面的XPath是相对于引用displaynode元素的<DisplaysCfg>。因此,XPath将针对整个XML文档进行评估。

将XPath更改为从当前attrib中选择子节点,您就可以了:

For Each displaynode In xmldoc.SelectNodes("/DisplaysCfg")
    Dim screenname As String = ""
    For Each attrib As XmlElement In displaynode
        screenname = attrib.GetAttribute("NAME")
        Debug.Print(screenname)
        'Notes changes at the following line: '
        For Each symbolnode In attrib.SelectNodes("./*")
            For Each tagattrib As XmlElement In symbolnode
                If tagattrib.Name = "TAG" Then
                    Debug.Print("--" & tagattrib.GetAttribute("NAME"))
                End If
            Next
        Next
    Next
Next