在VB6中粉碎XML /查找最大属性值

时间:2018-10-27 22:58:17

标签: xml vb6 max shred

我是新来的人-我希望将其发布在正确的位置。

作为下面我的帖子的更新,我找到了一种获取地址的城市部分的方法。我真的不需要原始帖子中建议的最大值;我只需要最后一个值,因为“ xyz:sequenceNumber”值始终按顺序排列。所以我尝试了这个:

tmpCity = xNode.selectSingleNode("//abc:Person//xyz:Region").previousSibling.Text

似乎可行,因为我正在处理格式良好的.xml文件,其中xyz:Region的previousSibling始终是xyz:AddressText的最后一行,其中包含我要查找的City值。我仍然感谢任何评论,因为对于这个(以及下面的代码)是否甚至在远程上还是有效的,我还是一无所知。我要切碎许多大的.xml文件,因此效率很重要。

我需要处理一些过时的VB6代码,其中包括递归XML分解子例程。我熟悉VB6,但是我不理解此子例程。我在下面粘贴了一部分代码。我希望有人可以向我指出一些详细的背景阅读材料,这些材料将帮助我弄清楚该子例程的XML处理方面是如何工作的,以便我可以维护和修改它。我还粘贴了我需要使用的两个XML文件的[经过消毒]的示例摘录。一个问题是地址的城市部分存储在一系列枚举属性的最后一个中。要获得城市,我需要从具有最大xyz:sequenceNumber值的属性中提取文本。 SO有很多示例,其中包含如何获取最高价值属性的示例,但是我无法让它们在此子例程中工作。通常,他们似乎使用了max()函数,当我试图在此子例程中使用它时,VB6会抱怨该函数;或它们使用的内容与您在下面的代码段中看到的类似,但是当我尝试改编时,VB6抱怨双冒号(“ ::”)。

doc.SelectSingleNode("//Employees/Employee/@Id[not(. <=../preceding-sibling::Employee/@id) and not(. <=../following-sibling::Employee/@Id)]");

我想我所看到的示例与VB6中可用的库属于不同的库。

这是XML示例:

<abc:Person>
  <xyz:LicenseNo>1234</xyz:LicenseNo>
  <xyz:Language xyz:languageCode="en">
    <xyz:Name>
      <xyz:Company xyz:languageCode="en">ABC Company Ltd.</xyz:Company>
    </xyz:Name>
    <xyz:AddressCollection>
      <xyz:Address>
        <xyz:SequencedAddress xyz:languageCode="en">
          <xyz:AddressText xyz:sequenceNumber="1">The ABC Building</xyz:AddressText>
          <xyz:AddressText xyz:sequenceNumber="2">123 Main Street</xyz:AddressText>
          <xyz:AddressText xyz:sequenceNumber="3">3rd Floor</xyz:AddressText>
          <xyz:AddressText xyz:sequenceNumber="4">Tampa</xyz:AddressText>
          <xyz:Region xyz:RegionCategory=“State”>FL</xyz:Region>
          <xyz:CountryCode>US</xyz:CountryCode>
          <xyz:ZipCode>33607</xyz:ZipCode>
        </xyz:SequencedAddress>
      </xyz:Address>
    </xyz:AddressCollection>
  </xyz:Language>
</abc:Person>
<abc:Person>
  <xyz:LicenseNo>567</xyz:LicenseNo>
  <xyz:Language xyz:languageCode="en">
    <xyz:Name>
      <xyz:Company xyz:languageCode="en">XYZ Industries Ltd.</xyz:Company>
    </xyz:Name>
    <xyz:AddressCollection>
      <xyz:Address>
        <xyz:SequencedAddress xyz:languageCode="en">
          <xyz:AddressText xyz:sequenceNumber="1">XYZ Factory Plaza</xyz:AddressText>
          <xyz:AddressText xyz:sequenceNumber="2">678 Elm Street</xyz:AddressText>
          <xyz:AddressText xyz:sequenceNumber="3">Orlando</xyz:AddressText>
          <xyz:Region xyz:RegionCategory=“State”>FL</xyz:Region>
          <xyz:CountryCode>US</xyz:CountryCode>
          <xyz:ZipCode>32814</xyz:ZipCode>
        </xyz:SequencedAddress>
      </xyz:Address>
    </xyz:AddressCollection>
  </xyz:Language>
</abc:Person>

这是代码部分:

Public Sub ShredXML(ByRef Nodes As MSXML2.IXMLDOMNodeList)
Dim xNode As MSXML2.IXMLDOMNode

    For Each xNode In Nodes
            If xNode.nodeType = NODE_ELEMENT Then
                If xNode.nodeName = "abc:Person" Then
                tmpCompany = xNode.selectSingleNode("//abc:Person//xyz:Company").Text
                tmpLicenseNo = xNode.selectSingleNode("//abc:Person//xyz:LicenseNo").Text
                tmpLanguage = xNode.selectSingleNode("//abc:Person//xyz:Language").Attributes.getNamedItem("xyz:languageCode").Text
                tmpRegion = xNode.selectSingleNode("//abc:Person//xyz:Region").Text
                tmpCountryCode = xNode.selectSingleNode("//abc:Person//xyz:CountryCode").Text
                tmpZipCode = xNode.selectSingleNode("//abc:Person//xyz:ZipCode").Text

‘ database insert code omitted

                End If
            End If

        If xNode.hasChildNodes Then
            ShredXML xNode.childNodes
        End If

   Next xNode

1 个答案:

答案 0 :(得分:0)

我获取了示例XML代码段,修复了错误(使用了错误的引号,用“State”代替了"State",然后将其包装在文档节点中:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<doc xmlns:abc="urn:abc" xmlns:xyz="urn:xyz">
:
</doc>

将其另存为sample.xml并运行以下代码:

Option Explicit

Private Sub WriteLine(Optional ByVal Text As String)
    With Text1
        .SelStart = &H7FFF 'End.
        If Len(Text) > 0 Then .SelText = Text
        .SelText = vbNewLine
    End With
End Sub

Private Sub Form_Load()
    Dim ParseSuccess As Boolean
    Dim Element1 As MSXML2.IXMLDOMElement
    Dim Element2 As MSXML2.IXMLDOMElement
    Dim LicenseNo As String
    Dim Company As String
    Dim Language As String
    Dim Region As String
    Dim CountryCode As String
    Dim ZipCode As String
    Dim MaxSeqVal As Long
    Dim MaxSeqElement As MSXML2.IXMLDOMElement
    Dim SeqVal As Long
    Dim City As String

    With New MSXML2.DOMDocument60
        ParseSuccess = .Load(App.Path & "\sample.xml")
        WriteLine "Parse success = " & CStr(ParseSuccess)
        If ParseSuccess Then
            WriteLine
            For Each Element1 In .getElementsByTagName("abc:Person")
                With Element1
                    LicenseNo = .getElementsByTagName("xyz:LicenseNo")(0).Text
                    Company = .getElementsByTagName("xyz:Company")(0).Text
                    Set Element2 = .getElementsByTagName("xyz:Language")(0)
                    Language = Element2.getAttribute("xyz:languageCode")
                    Region = .getElementsByTagName("xyz:Region")(0).Text
                    CountryCode = .getElementsByTagName("xyz:CountryCode")(0).Text
                    ZipCode = .getElementsByTagName("xyz:ZipCode")(0).Text
                    MaxSeqVal = -1
                    For Each Element2 In .getElementsByTagName("xyz:AddressText")
                        SeqVal = CLng(Element2.getAttribute("xyz:sequenceNumber"))
                        If SeqVal > MaxSeqVal Then
                            MaxSeqVal = SeqVal
                            Set MaxSeqElement = Element2
                        End If
                    Next
                    City = MaxSeqElement.Text
                End With
                WriteLine LicenseNo
                WriteLine Company
                WriteLine Language
                WriteLine Region
                WriteLine CountryCode
                WriteLine ZipCode
                WriteLine City
                WriteLine
            Next
        End If
    End With
End Sub

请注意,Node和Element接口具有不同的成员(属性和方法),这就是为什么在此使用Element1Element2的原因。这样我们就可以获取一个Node并查询其更有用的Element接口。

似乎工作正常:

Parse success = True

1234
ABC Company Ltd.
en
FL
US
33607
Tampa

567
XYZ Industries Ltd.
en
FL
US
32814
Orlando

据我所知,MSXML不支持XPath 2,因此不支持“最大”操作。