xslt - 将ANY xml转换为表格

时间:2011-08-27 09:53:39

标签: xml excel xslt

我正在尝试创建一个通用的XSLT文件来处理任何xml输入,因为我不想引用xslt中的特定子节点,因为xml可能是任何东西。我不希望xml的层次结构比10个子节点更深。

示例xml:

   <Client>
      <LastName>Bill</LastName>
      <FirstName>Gates</FirstName>
      <MiddleName/>
      <Suffix/>
      <DateOfBirth>30-May-1968</DateOfBirth>
      <PlaceOfBirth/>
      <SSN>n/a</SSN>
      <Gender>Male</Gender>
      <District>
        <City>SHELTON</City>
        <Mayor>wong</Mayor>
      </District>
      <State>WA</State>
      <Zip>96484</Zip>
   </Client>
   <Client>
      <LastName>Warron</LastName>
      <FirstName>Buffet</FirstName>
      <MiddleName>P</MiddleName>
      <Suffix/>
      <DateOfBirth>12-Aug-1957</DateOfBirth>
      <PlaceOfBirth>Mississippi</PlaceOfBirth>
      <SSN>n/a</SSN>
      <Gender>Male</Gender>
      <City>Missi</City>
      <State>KS</State>
      <Account>
        <Type>
        <Name>Cash</Name>
        <Currency>USD</Currency>
        <Country>USA</Country>
        </Type>
      </Account>
      <Zip>66096</Zip>
   </Client>
到目前为止

xslt:

<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>
  <xsl:attribute name="ss:Name">
  <xsl:value-of select="local-name(/*/*)"/>
  </xsl:attribute>
    <Table x:FullColumns="1" x:FullRows="1">
      <Row>
        <xsl:for-each select="*[position() = 1]/*">
          <Cell><Data ss:Type="String">
          <xsl:value-of select="local-name()"/>
          </Data></Cell>
        </xsl:for-each>
      </Row>
      <xsl:apply-templates/>
    </Table>
  </Worksheet>
</xsl:template>


<xsl:template match="/*/*">
  <Row>
    <xsl:apply-templates/>
  </Row>
</xsl:template>


<xsl:template match="/*/*/*">
  <Cell><Data ss:Type="String">
    <xsl:value-of select="."/>
  </Data></Cell>
</xsl:template>


</xsl:stylesheet>

我使用这个VBA宏来完成所有操作:

Private Sub CommandButton1_Click()
Dim sourceFile As String
Dim xlstFile As String
Dim exportFile As String
Dim filePath As String

filePath = Application.ThisWorkbook.path

sourceFile = filePath & "\client.xml"
xlstFile = filePath & "\trans.xml"
exportFile = filePath & "\export1.xls"

Transform sourceFile, xlstFile, exportFile
End Sub
Private Sub Transform(sourceFile, stylesheetFile, resultFile)

Dim source As New MSXML2.DOMDocument30
Dim stylesheet As New MSXML2.DOMDocument30
Dim result As New MSXML2.DOMDocument30

' Load data.
source.async = False
source.Load sourceFile

' Load style sheet.
stylesheet.async = False
stylesheet.Load stylesheetFile

If (source.parseError.ErrorCode <> 0) Then
   MsgBox ("Error loading source document: " & source.parseError.reason)
   Else
If (stylesheet.parseError.ErrorCode <> 0) Then
      MsgBox ("Error loading stylesheet document: " & stylesheet.parseError.reason)
   Else
      ' Do the transform.
      source.transformNodeToObject stylesheet, result
      result.Save resultFile
End If
End If

End Sub

期望的输出(类似于此):

LastName    FirstName   MiddleName  Suffix  DateOfBirth PlaceOfBirth    SSN Gender  District    State   Zip
Bill    Gates           30-May-1968     n/a Male     SHELTON wong    WA 96484
Warron  Buffet  P       12-Aug-1957 Mississippi n/a Male    Missi   KS  66096
Steev   Jobbs           19-Apr-1959 Cupertino   n/a Male    Cupertino   CA  96066

如果其中一个xmls没有某个标签,则只在表格中显示一个空白单元格。标签作为列标题的顺序并不重要。目前xslt没有处理具有不同结构的xmls。

1 个答案:

答案 0 :(得分:1)

如果你真的想要将任何xml转换为表格,那么你可以做到,但它不是一个非常漂亮的表格。 (一些支持XML的关系数据库有一个名为“shredding”的操作,试图这样做。)你当然不能通过一个使用普通XML的样式表然后尝试对它进行概括来实现它。