xslt - конвертировать ЛЮБОЙ XML в таблицу - PullRequest
0 голосов
/ 27 августа 2011

Я пытаюсь создать универсальный 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>

Iиспользуйте этот макрос 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 Ответ

1 голос
/ 28 августа 2011

Если вы действительно хотите преобразовать ЛЮБОЙ XML в таблицу, то вы можете это сделать, но это не будет очень красивой таблицей. (В некоторых реляционных базах данных, поддерживающих XML, есть операция под названием «уничтожение», которая пытается это сделать.) Вы, конечно, не можете сделать это, взяв таблицу стилей, которая работает с тривиальным XML, и затем попытайтесь обобщить ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...