Merge elements when exporting to XML

时光总嘲笑我的痴心妄想 提交于 2019-12-02 04:15:17

Excel is only able directly exporting XML in table form. This is a sequence of data rows (records) in which each data field has exactly one element. It is not able exporting list of lists. That is: One list of items has a second list of items. See https://support.office.com/en-us/article/Export-XML-data-0b21f51b-56d6-48f0-83d9-a89637cd4360.

But you want list of lists. A sequence of Groups, each with a sequence of Cities. The schema would be:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="list">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Group" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="City" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element type="xs:string" name="value"/>
                  </xs:sequence>
                  <xs:attribute type="xs:string" name="name"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute type="xs:string" name="name"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

But as documented this can't be exported directly with Excel's XML export feature.

So I suggest using VBA for this. The following will create the needed XML from the shown data.

Sub testXLStoXML()

 Set oXMLDoc = CreateObject("MSXML2.DOMDocument")
 Set oPI = oXMLDoc.createProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8"" standalone=""yes""")
 Set oRoot = oXMLDoc.createNode(1, "list", "")
 oXMLDoc.appendChild oRoot
 oXMLDoc.InsertBefore oPI, oXMLDoc.ChildNodes.Item(0)

 With ActiveSheet

  lRow = 2
  sGroupName = ""

  Do While .Cells(lRow, 1).Value <> ""

   sGroupName = .Cells(lRow, 1).Value
   Set oElmGroup = oXMLDoc.createNode(1, "Group", "")
   oXMLDoc.DocumentElement.appendChild oElmGroup
   Set oAttr = oXMLDoc.createNode(2, "name", "")
   oAttr.NodeValue = sGroupName
   oElmGroup.setAttributeNode oAttr

   Do While .Cells(lRow, 1).Value = sGroupName

    Set oElmCity = oXMLDoc.createNode(1, "City", "")
    Set oAttr = oXMLDoc.createNode(2, "name", "")
    oAttr.NodeValue = .Cells(lRow, 2).Value
    oElmCity.setAttributeNode oAttr

    Set oElmValue = oXMLDoc.createNode(1, "Value", "")
    oElmValue.appendChild oXMLDoc.createTextNode(.Cells(lRow, 3).Value)

    oElmCity.appendChild oElmValue
    oElmGroup.appendChild oElmCity

    lRow = lRow + 1

   Loop

  Loop

 End With

 MsgBox oXMLDoc.XML

 oXMLDoc.Save "test.xml"

End Sub

The Worksheet with the shown data must be the active worksheet while the macro is running.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!