XSL通用垂直表

时间:2018-01-22 11:09:47

标签: xml xslt

我正在尝试编写一个XSL来将我的XML转换为垂直表。我不知道现有的元素。突然间可能会出现一个IBAN元素,但它会存在于所有书籍中。输入如下:

<Library>
  <Book>
    <Title>Foo</Title>
    <ThisMaybeHere>Some Value</ThisMaybeHere>
    <DontKnowAboutThis>Also Value</DontKnowAboutThis>
  </Book>
  <Book>
    <Title>Bar</Title>
    <ThisMaybeHere>Some Value</ThisMaybeHere>
    <DontKnowAboutThis>Also Value</DontKnowAboutThis>
  </Book>
</Library>

所需的输出为:

Title             | Foo        | Bar
ThisMaybeHere     | Some Value | Some value
DontKnowAboutThis | Also Value | Also Value

到目前为止我尝试了什么:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/Library">
    <table>
      <xsl:for-each select="//Book/*">
        <tr>
          <td>
            <xsl:value-of select="local-name()"/>
          </td>
          <td>
            <xsl:value-of select="."/>
          </td>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>

这导致下表:

<!-- First Book !-->
Title             | Foo
ThisMaybeHere     | Some Value
DontKnowAboutThis | Also Value
<!-- Second Book !-->
Title             | Bar
ThisMaybeHere     | Some Value
DontKnowAboutThis | Also Value

所以它首先循环通过书籍然后通过值。如上所述,获得所需输出的可能解决方案是什么?

非常感谢!

1 个答案:

答案 0 :(得分:1)

以下解决方案使用第一个Book子项的元素名称作为第一列的名称。然后,它使用当前子项的位置作为所有//Book s的索引,表达式为//Book/*[$pos]

只有在每个Book元素中子项的顺序相同时,此方法才有效。否则它会失败。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/Library">
    <table>
      <xsl:for-each select="Book[1]/*">
        <xsl:variable name="pos" select="position()" />
        <tr>
          <td>
            <xsl:value-of select="local-name()"/>
          </td>
          <xsl:for-each select="//Book/*[$pos]">
            <td>
              <xsl:value-of select="."/>
            </td>
          </xsl:for-each>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>