获取包含来自另一个节点集 XSLT1.0 的值的节点集



我使用的是XSLT1.0,不能使用任何扩展名。我有一个节点集,需要找到另一个节点集中包含第一个值的所有元素,并将它们列为相关节点。

下面的示例有点做作,因为我正在使用的 XML 非常大并且包含机密数据,所以我编造了一些数据。

在下面的 XML 示例中,我正在处理集合。当我到达set_no 1时,我发现有子集1,2和3。然后,我需要sub_sec按顺序查找并列出所有书籍/章节/部分/sub_section/sub_sec元素,其sec_no为 1,2,3(set/set1/sub_set 值)

所以我的结果应该是:

set1 
A
B
C
D
E
F
G
set2
A
B
C
D
G 

在SQL中,它将是一个IN子句

    <?xml version="1.0" encoding="UTF-8"?>
<root>
    <sets>
        <set>
            <set_no>1</set_no>
            <sub_sets>
                <sub_set>1</sub_set>
                <sub_set>2</sub_set>
                <sub_set>3</sub_set>
            </sub_sets>
        </set>
        <set>
            <set_no>2</set_no>
            <sub_sets>
                <sub_set>1</sub_set>
                <sub_set>3</sub_set>
            </sub_sets>
        </set>
    </sets>
    <book>
        <chapter>
            <section>
                <sec_no>1</sec_no>
                <sub_section>
                    <sub_sec>A</sub_sec>
                    <sub_sec>B</sub_sec>
                    <sub_sec>C</sub_sec>
                    <sub_sec>D</sub_sec>
                    <sub_sec>G</sub_sec>
                </sub_section>
            </section>
            <section>
                <sec_no>2</sec_no>
                <sub_section>
                    <sub_sec>E</sub_sec>
                    <sub_sec>F</sub_sec>
                </sub_section>
            </section>
        </chapter>
    </book>
</root>

我被困在如何在 XSLT1.0 中执行此操作

我这样做的方式是遍历集合,然后为每个集合迭代各个部分。这一直有效,直到要求更改为按sub_sec排序(因此对多个部分进行排序)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

    <xsl:template match="root">
        <html>
            <body>
                <xsl:for-each select="sets/set">
                    <xsl:variable name="curr_set" select="set_no"/> 
                    Set: <xsl:value-of select="$curr_set"/>
                    <br/>
                    <xsl:for-each select="sub_sets/sub_set">
                        <xsl:variable name="curr_sub_set" select="node()"/> 
                        <!--Curr-Sub-Set: <xsl:value-of select="$curr_sub_set"/><br/>-->
                        <xsl:for-each select="/root/book/chapter/section[sec_no=$curr_sub_set]/sub_section/sub_sec">
                            <xsl:value-of select="."/><br />
                        </xsl:for-each>
                    </xsl:for-each>
                    <br/><br/>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

这应该有效:

<xsl:template match="root">
    <html>
        <body>
            <xsl:for-each select="sets/set">
                Set: <xsl:value-of select="set_no"/>
                <br/>
                <xsl:for-each select="/root/book/chapter/section[sec_no=current()/sub_sets/sub_set]/sub_section/sub_sec">
                    <xsl:sort select="."/>
                    <xsl:value-of select="."/><br />                    
                </xsl:for-each>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

这会产生:

Set: 1<br>A<br>B<br>C<br>D<br>E<br>F<br>G<br>
Set: 2<br>A<br>B<br>C<br>D<br>G<br>

输出按您的要求排序。

在谓词表达式 [sec_no=current()/sub_sets/sub_set] 中,current() 绑定到正在计算的集合,因此 current()/sub_sets/sub_set 获取当前集合sub_set值的列表。 当sec_no在此列表中时,谓词将为真。

这种类型的问题最好使用键来解决:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="sub_sec-by-sec_no" match="sub_sec" use="ancestor::section/sec_no" />
<xsl:template match="/root">
    <html>
        <body>
            <xsl:for-each select="sets/set">
                Set: <xsl:value-of select="set_no"/>
                <br/>
                <xsl:for-each select="key('sub_sec-by-sec_no', sub_sets/sub_set)">
                    <xsl:sort select="." data-type="text" order="ascending"/>
                    <xsl:value-of select="."/>
                    <br/>
                </xsl:for-each>
                <br/><br/>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>
</xsl:stylesheet>

相关内容

  • 没有找到相关文章

最新更新