Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 遍历同级,直到指定元素类型_Xslt_Xslt 1.0 - Fatal编程技术网

Xslt 遍历同级,直到指定元素类型

Xslt 遍历同级,直到指定元素类型,xslt,xslt-1.0,Xslt,Xslt 1.0,我有一个平面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&

我有一个平面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>

第一个标题
要素1:1
要素1:2
第二个标题
要素2:1
要素3:1
第三头球
要素3:1
要素3:2
要素3:3
要素3:4
本质上,报头的数量未知。每个标题下都有未知数量的元素(不同类型的树)。每个标题下可以有零到多个每种类型的元素。我无法控制此结构,因此无法更改/改进它

我试图生成的是以下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>
第一个标题
类型1
要素1:1
类型2
要素1:2
第二个标题
类型1
要素2:1
类型3
要素2:2
第三头球
类型1
要素3:1
类型2
要素3:2
类型1
要素3:3
类型2
要素3:4
每个标题将是一个HTML标题(级别2),然后我希望所有其他元素直到下一个标题显示在表中

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

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

???
我想我可以用代码来替换“?”,在下一个header元素之前遍历以下所有同级元素,并将它们转换为表行

这是个好主意吗

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


我正在使用XSLT1.0。

实现这一点的一种方法是使用一个键,按照非标题元素前面的第一个
标题
元素对其进行分组

<xsl:key name="type" match="*[not(self::header)]" use="generate-id(preceding-sibling::header[1])" />
在与此
标题
元素匹配的模板中,您可以使用键获取与标题对应的所有
类型
元素

<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
转换为
type1
的问题,但我将把这个练习留给您

<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>