在Excel中将XML子项导入为列

时间:2017-01-03 18:55:20

标签: xml excel vba xslt

我有几个大型XML文件需要转换为Excel电子表格。一些数据是嵌套的,当我导入到Excel时,它会为每个子值创建额外的行。我想创建一个列来处理孩子,所以每个项目只有一行。以下是XML的示例:

<Items>
    <Item MaintenanceType="C">
      <PartNumber>ABC123</PartNumber>
      <BrandLabel>Brand X</BrandLabel>
      <Descriptions>
        <Description MaintenanceType="C" DescriptionCode="DES" LanguageCode="EN" Sequence="1">This is a short description</Description>
        <Description MaintenanceType="C" DescriptionCode="EXT" LanguageCode="EN" Sequence="1">This is a little longer description</Description>
        <Description MaintenanceType="C" DescriptionCode="MKT" LanguageCode="EN" Sequence="1">This is a reallllllllllly long description</Description>
        <Description MaintenanceType="C" DescriptionCode="ASC" LanguageCode="EN" Sequence="1">Another Description</Description>
        <Description MaintenanceType="C" DescriptionCode="SHO" LanguageCode="EN" Sequence="1">ShortDesc</Description>
      </Descriptions>
      <Prices>
        <Pricing MaintenanceType="C" PriceType="LST">
          <PriceSheetNumber>J16</PriceSheetNumber>
          <CurrencyCode>USD</CurrencyCode>
          <EffectiveDate>2016-01-05</EffectiveDate>
          <Price UOM="PE">191.0000</Price>
        </Pricing>
        <Pricing MaintenanceType="C" PriceType="RET">
          <PriceSheetNumber>J16</PriceSheetNumber>
          <CurrencyCode>USD</CurrencyCode>
          <EffectiveDate>2016-01-05</EffectiveDate>
          <Price UOM="PE">191.0000</Price>
        </Pricing>
        <Pricing MaintenanceType="C" PriceType="RMP">
          <PriceSheetNumber>J16</PriceSheetNumber>
          <CurrencyCode>USD</CurrencyCode>
          <EffectiveDate>2016-01-05</EffectiveDate>
          <Price UOM="PE">181.4500</Price>
        </Pricing>
      </Prices>
      <DigitalAssets>
        <DigitalFileInformation MaintenanceType="C" LanguageCode="EN">
          <FileName>itemimage.jpg</FileName>
          <AssetType>P07</AssetType>
          <FileType>JPG</FileType>
          <Representation>R</Representation>
          <FileSize>76</FileSize>
          <Resolution>300</Resolution>
          <ColorMode>RGB</ColorMode>
          <Background>WHI</Background>
          <OrientationView>ANG</OrientationView>
          <AssetDimensions UOM="PX">
            <AssetHeight>1367</AssetHeight>
            <AssetWidth>1500</AssetWidth>
          </AssetDimensions>
          <URI>http://www.itemimageassets.xcom/ImgVDHR/BrandX/ABC123.jpg</URI>
        </DigitalFileInformation>
      </DigitalAssets>
    </Item>
</Items>

我创建的XSLT就是这个(我知道这是错误的,但不知道为什么会这么说):

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
    xmlns="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:user="urn:my-scripts"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" > 

    <xsl:template match="/">
        <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
            xmlns:o="urn:schemas-microsoft-com:office:office"
            xmlns:x="urn:schemas-microsoft-com:office:excel"
            xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
            xmlns:html="http://www.w3.org/TR/REC-html40">
            <xsl:apply-templates/>
        </Workbook>
    </xsl:template>

    <xsl:template match="/*">
        <Worksheet>
            <Table x:FullColumns="1" x:FullRows="1">
                <Row>
                    <xsl:for-each select="/PIES/Items/Item">
                        <Cell><Data ss:Type="String">
                            <xsl:value-of select="ItemLevelGTIN/text()"/>
                        </Data></Cell>
                        <Cell><Data ss:Type="String">
                            <xsl:value-of select="PartNumber/text()"/>
                        </Data></Cell>
                        <Cell><Data ss:Type="String">
                            <xsl:value-of select="SubBrandLabel/text()"/>
                        </Data></Cell>
                        <Cell><Data ss:Type="String">
                            <xsl:value-of select="Descriptions/Description/text()"/>
                        </Data></Cell>
                        <Cell><Data ss:Type="String">
                            <xsl:value-of select="Descriptions/Description/text()"/>
                        </Data></Cell>
                        <Cell><Data ss:Type="String">
                            <xsl:value-of select="Prices/Pricing/Price/text()"/>
                        </Data></Cell>
                        <Cell><Data ss:Type="String">
                            <xsl:value-of select="Prices/Pricing/Price/text()"/>
                        </Data></Cell>
                    </xsl:for-each>     
                </Row>
            </Table>
        </Worksheet>
    </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

作为一个开放式文件结构,XML树可以为设计者留下许多维度。但是,表格式结构(如电子表格或数据库表格)是二维的(逐列),因此相应的XML必须是每行的一个子级别设置:

<data> 
  <row>
    <col>data</col>
    <col>data</col>
    <col>data</col>
    <col>data</col>
    <col>data</col>
   </row>
</data>

因此,相应地构建您的XSLT,将重复元素 Item 重新设置为一个扁平的一级子集。下面使用XPath表达式向下遍历<Item>节点,以根据属性值选择嵌套子节点。 <xsl:value-of>用于检索仅包含在新标记名称中的文本值,<xsl:copy-of>复制现有标记名称和文本值。

XSLT (另存为.xsl文件)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />

  <xsl:template match="Items">
    <xsl:copy>
      <xsl:apply-templates select="Item"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Item">
    <xsl:copy>      
      <xsl:copy-of select="PartNumber"/>
      <xsl:copy-of select="BrandLabel"/>
      <ShortDescription><xsl:value-of select="Descriptions/Description[@DescriptionCode='DES']"/></ShortDescription>      
      <LongDescription><xsl:value-of select="Descriptions/Description[@DescriptionCode='EXT']"/></LongDescription>
      <Price_LST><xsl:value-of select="Prices/Pricing[@PriceType='LST']/Price"/></Price_LST>
      <Price_RMP><xsl:value-of select="Prices/Pricing[@PriceType='RMP']/Price"/></Price_RMP>
      <xsl:copy-of select="DigitalAssets/DigitalFileInformation/*[local-name()!='AssetDimensions']"/>
      <xsl:copy-of select="DigitalAssets/DigitalFileInformation/AssetDimensions/*"/>      
    </xsl:copy>
  </xsl:template>

</xsl:transform>

VBA (使用MSXML库)

Public Sub RunXSLT()
    ' REFERENCE Microsoft XML, v6.0
    Dim xmlDoc As New MSXML2.DOMDocument60, xslDoc As New MSXML2.DOMDocument60, newDoc As New MSXML2.DOMDocument60

    xmlDoc.Load "C:\Path\To\Input.xml"
    xmlDoc.async = False

    xslDoc.Load "C:\Path\To\XSLTScript.xsl"
    xslDoc.async = False

    xmlDoc.transformNodeToObject xslDoc, newDoc
    newDoc.Save "C:\Path\To\Output.xml"

    Set newDoc = Nothing: Set xslDoc = Nothing: Set xmlDoc = Nothing

    ' IMPORT XML INTO NEW WORKBOOK
    Workbooks.OpenXML "C:\Path\To\Output.xml", , xlXmlLoadImportToList          
End Sub

<强>输出

XML已转换

<?xml version="1.0" encoding="UTF-8"?>
<Items>
    <Item>
        <PartNumber>ABC123</PartNumber>
        <BrandLabel>Brand X</BrandLabel>
        <ShortDescription>This is a short description</ShortDescription>
        <LongDescription>This is a little longer description</LongDescription>
        <Price_LST>191.0000</Price_LST>
        <Price_RMP>181.4500</Price_RMP>
        <FileName>itemimage.jpg</FileName>
        <AssetType>P07</AssetType>
        <FileType>JPG</FileType>
        <Representation>R</Representation>
        <FileSize>76</FileSize>
        <Resolution>300</Resolution>
        <ColorMode>RGB</ColorMode>
        <Background>WHI</Background>
        <OrientationView>ANG</OrientationView>
        <URI>http://www.itemimageassets.xcom/ImgVDHR/BrandX/ABC123.jpg</URI>
        <AssetHeight>1367</AssetHeight>
        <AssetWidth>1500</AssetWidth>
    </Item>
</Items>

Excel表格导入

Excel Table Import

答案 1 :(得分:0)

这并没有为您提供您建议的确切输出,但它比原始xml更有用:

  • 点击开发者&gt;导入。

  • 在“导入XML”对话框中,找到并选择XML数据文件 要导入的(.xml),然后单击“导入”。

https://support.office.com/en-us/article/Import-XML-data-6eca3906-d6c9-4f0d-b911-c736da817fa4?ui=en-US&rs=en-US&ad=US#bmimport_an_xml_file_as_an_xml_list_wit