通过兄弟姐妹迭代直至特定元素类型



我的XML结构看起来像这样:

<root>
    <header>First header</header>
    <type1>Element 1:1</type1>
    <type2>Element 1:2</type2>
    <header>Second header</header>
    <type1>Element 2:1</type1>
    <type3>Element 3:1</type3>
    <header>Third header</header>
    <type1>Element 3:1</type1>
    <type2>Element 3:2</type2>
    <type1>Element 3:3</type1>
    <type2>Element 3:4</type2>
</root>

当然,标题数量未知。在每个标头下,都有未知数的元素(树不同类型)。每个标头下方的每种类型的许多元素可能为零。我无法控制这种结构,因此我无法更改/改进。

我要生成的是此html:

<h2>First header</h2>
<table>
    <tr>
        <th>Type 1</th>
        <td>Element 1:1</td>
    </tr>
    <tr>
        <th>Type 2</th>
        <td>Element 1:2</td>
    </tr>
</table>
<h2>Second header</h2>
<table>
    <tr>
        <th>Type 1</th>
        <td>Element 2:1</td>
    </tr>
    <tr>
        <th>Type 3</th>
        <td>Element 2:2</td>
    </tr>
</table>
<h2>third header</h2>
<table>
    <tr>
        <th>Type 1</th>
        <td>Element 3:1</td>
    </tr>
    <tr>
        <th>Type 2</th>
        <td>Element 3:2</td>
    </tr>
    <tr>
        <th>Type 1</th>
        <td>Element 3:3</td>
    </tr>
    <tr>
        <th>Type 2</th>
        <td>Element 3:4</td>
    </tr>
</table>

每个标头将是HTML标头(级别2),然后我希望所有其他元素直到下一个标头

我的第一个想法是制作与标题元素匹配的模板:

<xsl:template match="header">
    <h2><xsl:value-of select="text()" /></h2>
    <table>
        ???
    </table>
</xsl:template>

我认为我可以替换"?"在兄弟姐妹之后的所有上进行代码迭代,直到下一个标头元素并将它们变成表行。

这是一个好主意吗?

如果是,我该怎么做?如果不是,什么是更好的解决方案?

我正在使用XSLT 1.0。

实现此目的的一种方法,将非头部元素通过其先前的header元素

分组
<xsl:key name="type" match="*[not(self::header)]" use="generate-id(preceding-sibling::header[1])" />

然后,您将仅选择header Elements

开始
<xsl:apply-templates select="header" />

以及与此header元素匹配的模板中,您可以通过使用键

获得与标头相对应的所有type元素
<xsl:for-each select="key('type', generate-id())">

尝试此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes" />
    <xsl:key name="type" match="*[not(self::header)]" use="generate-id(preceding-sibling::header[1])" />
    <xsl:template match="root">
        <xsl:apply-templates select="header" />
    </xsl:template>
    <xsl:template match="header">
        <h2><xsl:value-of select="." /></h2>
        <table>
            <xsl:for-each select="key('type', generate-id())">
                <tr>
                    <th><xsl:value-of select="local-name()" /></th>
                    <th><xsl:value-of select="." /></th>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

请注意,这不包括将节点名称type1转换为Type 1的问题,但我将为您留下该练习....

相关内容

  • 没有找到相关文章

最新更新