XPATH 轴 - 问题

发布于 2024-11-03 14:39:40 字数 1829 浏览 4 评论 0原文

XML 结构:

<units>
    <unit>
        <lesson>
            <name>Sample 1</name>
            <sections>
                <section type="IN">
                    <title> Sample Title 1 </title>
                </section>
            </sections>
        </lesson>
        <lesson>
            <name>Sample 2</name>
            <sections>
                <section type="OF">
                    <title> Sample Title 2 </title>
                </section>
            </sections>
        </lesson>
        <lesson>
            <name>Sample 3</name>
            <sections>
                <section type="IN">
                    <title> Sample Title 3</title>
                </section>
            </sections>
        </lesson>
        <lesson>
            <name>Sample 4</name>
            <sections>
                <section type="AS">
                    <title> Sample Title 4</title>
                </section>
            </sections>
        </lesson>
        <lesson>
            <name>Sample 5</name>
            <sections>
                <section type="IN">
                    <title> Sample Title 5</title>
                </section>
            </sections>
        </lesson>
    </unit>
</units>

我的要求是获取 title 元素的值并显示如下(对相似的数据进行分组并显示)

IN:
Sample Title 1
Sample Title 3
Sample Title 5
OF:
Sample Title 2
AS:
Sample Title 5

我已使用 follow-sibling 选项来获取预期的输出。由于 XML 结构很大(我只粘贴了代码片段),因此我无法使用 ../../ 以及 XSLT 中的所有内容对路径进行硬编码。请帮助我获得预期的输出。

XML structure:

<units>
    <unit>
        <lesson>
            <name>Sample 1</name>
            <sections>
                <section type="IN">
                    <title> Sample Title 1 </title>
                </section>
            </sections>
        </lesson>
        <lesson>
            <name>Sample 2</name>
            <sections>
                <section type="OF">
                    <title> Sample Title 2 </title>
                </section>
            </sections>
        </lesson>
        <lesson>
            <name>Sample 3</name>
            <sections>
                <section type="IN">
                    <title> Sample Title 3</title>
                </section>
            </sections>
        </lesson>
        <lesson>
            <name>Sample 4</name>
            <sections>
                <section type="AS">
                    <title> Sample Title 4</title>
                </section>
            </sections>
        </lesson>
        <lesson>
            <name>Sample 5</name>
            <sections>
                <section type="IN">
                    <title> Sample Title 5</title>
                </section>
            </sections>
        </lesson>
    </unit>
</units>

My requirement is to get the values of title element and display as follows (Grouping similar data and display)

IN:
Sample Title 1
Sample Title 3
Sample Title 5
OF:
Sample Title 2
AS:
Sample Title 5

I have used following-sibling option to get the expected output. Since the XML structure is huge(I have pasted only the snippet), I cannot hard-code the path using ../../ and all in XSLT. Please help me in getting the expected output.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我不是你的备胎 2024-11-10 14:39:40

使用分组比任一同级轴更好地解决此问题:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:key name="bySectionType" match="section" use="@type" />
    <xsl:template match="/">
        <xsl:apply-templates select="units/unit/lesson/sections/section" />
    </xsl:template>
    <xsl:template match="section" />
    <xsl:template
        match="section[generate-id()=
                       generate-id(key('bySectionType', @type)[1])]">
        <xsl:value-of select="concat(@type, ':
')" />
        <xsl:apply-templates select="key('bySectionType', @type)" mode="out" />
    </xsl:template>
    <xsl:template match="section" mode="out">
        <xsl:value-of select="concat(normalize-space(title), '
')" />
    </xsl:template>
</xsl:stylesheet>

输出:

IN:
Sample Title 1
Sample Title 3
Sample Title 5
OF:
Sample Title 2
AS:
Sample Title 4

为了完整起见,以下样式表使用前面以下轴实现了相同的结果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:apply-templates select="units/unit/lesson/sections/section" />
    </xsl:template>
    <xsl:template match="section" />
    <xsl:template 
        match="section[not(preceding::section[@type=current()/@type])]">
        <xsl:value-of select="concat(@type, ':
')" />
        <xsl:apply-templates select=".|following::section[@type=current()/@type]"
            mode="out" />
    </xsl:template>
    <xsl:template match="section" mode="out">
        <xsl:value-of select="concat(normalize-space(title), '
')" />
    </xsl:template>
</xsl:stylesheet>

这是一个效率低得多的解决方案。解决这个问题的正常方法是使用 Muenchian 方法进行分组,如上所示。

It's better to solve this using grouping than either of the sibling axes:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:key name="bySectionType" match="section" use="@type" />
    <xsl:template match="/">
        <xsl:apply-templates select="units/unit/lesson/sections/section" />
    </xsl:template>
    <xsl:template match="section" />
    <xsl:template
        match="section[generate-id()=
                       generate-id(key('bySectionType', @type)[1])]">
        <xsl:value-of select="concat(@type, ':
')" />
        <xsl:apply-templates select="key('bySectionType', @type)" mode="out" />
    </xsl:template>
    <xsl:template match="section" mode="out">
        <xsl:value-of select="concat(normalize-space(title), '
')" />
    </xsl:template>
</xsl:stylesheet>

Output:

IN:
Sample Title 1
Sample Title 3
Sample Title 5
OF:
Sample Title 2
AS:
Sample Title 4

For completeness, the following stylesheet achieves the same result using the preceding and following axes:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:apply-templates select="units/unit/lesson/sections/section" />
    </xsl:template>
    <xsl:template match="section" />
    <xsl:template 
        match="section[not(preceding::section[@type=current()/@type])]">
        <xsl:value-of select="concat(@type, ':
')" />
        <xsl:apply-templates select=".|following::section[@type=current()/@type]"
            mode="out" />
    </xsl:template>
    <xsl:template match="section" mode="out">
        <xsl:value-of select="concat(normalize-space(title), '
')" />
    </xsl:template>
</xsl:stylesheet>

This is a far less efficient solution. The normal way to solve this is with the Muenchian Method for grouping, as shown above.

烟火散人牵绊 2024-11-10 14:39:40

这是 XSLT 2.0 中的解决方案:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:for-each-group select="//section" group-by="@type">
           <xsl:value-of select="@type, ':
'" separator=""/>
           <xsl:value-of select="current-group()/title" separator="
" />
           <xsl:value-of select="'
'"/>
        </xsl:for-each-group>              
    </xsl:template>
</xsl:stylesheet>

Here is the solution in XSLT 2.0:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:for-each-group select="//section" group-by="@type">
           <xsl:value-of select="@type, ':
'" separator=""/>
           <xsl:value-of select="current-group()/title" separator="
" />
           <xsl:value-of select="'
'"/>
        </xsl:for-each-group>              
    </xsl:template>
</xsl:stylesheet>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文