XSL - 在变量中存储唯一和排序的数据

Posted

技术标签:

【中文标题】XSL - 在变量中存储唯一和排序的数据【英文标题】:XSL - store unique and sorted data in a variable 【发布时间】:2018-11-17 03:53:25 【问题描述】:

使用 XSLT 2.0 和 Apache FOP 我希望能够创建一个新变量,在其中具有唯一且按 category 排序的值,但保留节点。所以新变量应该有以下节点:

<category>1. First Aid</category>
<category>2. Access control</category>
<category>3. Fire safety</category>
<category>4. Recognition</category>

输入的 XML 如下:

<equipment>
    <E0132>
        <category>1. First Aid</category>
        <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</description>
    </E0132>
    <E0133>
        <category>1. First Aid</category>
        <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</description>
    </E0133>
    <E4122>
        <category>3. Fire safety</category>
        <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</description>
    </E4122>
    <E4182>
        <category>3. Fire safety</category>
        <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</description>
    </E4182>
    <E4622>
        <category>2. Access control</category>
        <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</description>
    </E4622>
    <E5225>
        <category>4. Recognition</category>
        <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</description>
    </E5225>
</equipment>

关于 XSL,这是我目前所拥有的:

<xsl:variable name="equipment">
    <xsl:for-each-group select="//equipment/node()" group-by="category">
        <xsl:sort select="." order="ascending" />
        <xsl:value-of select="."/>              
    </xsl:for-each-group>        
</xsl:variable>

但它没有按预期工作。它不包含我想要的category 节点,我不知道如何在这里集成distinct-values() XSL 功能以实现唯一性。

【问题讨论】:

您应该(可能)使用xsl:copy-of 而不是xsl:value-of。但是,根据您实际尝试解决的问题,也许您根本不需要变量。如果您只是想创建某种“查找”,也许xsl:key 可以成为您的朋友?它将帮助您显示您期望的输出,并解释您在此处尝试实现的实际逻辑。谢谢! 【参考方案1】:

您可以使用current-grouping-key() 函数来存储值。下面是更新后的变量声明。

<xsl:variable name="equipment">
    <xsl:for-each-group select="//equipment/*/category" group-by=".">
        <xsl:sort select="." order="ascending" />
        <category>
            <xsl:value-of select="current-grouping-key()"/>
        </category>              
    </xsl:for-each-group>   
</xsl:variable>

检查变量内容

<xsl:copy-of select="$equipment" />

输出为

<category>1. First Aid</category>
<category>2. Access control</category>
<category>3. Fire safety</category>
<category>4. Recognition</category>

编辑:要在循环中打印变量值,请尝试以下操作

<!-- print variable values -->
<xsl:for-each select="$equipment/category" >
    <xsl:value-of select="." />
    <xsl:text>&#xA;</xsl:text>
</xsl:for-each>

输出

1. First Aid
2. Access control
3. Fire safety
4. Recognition

【讨论】:

但是我需要将该输出存储在一个变量中,然后我将使用该变量来获取和显示每个类别的description 您打算将node-set() 存储在变量中还是仅将变量中的值存储在以后可以循环遍历的变量中? 我的 XSL 知识非常有限,所以我相信我需要一个 node-set()。并且值必须是唯一的。 我已更新答案,将node-set() 存储在变量中,然后检查变量内容。 我实现了您的解决方案,但问题是,如果我在 $equipment 上运行 for-each,我会得到一个包含所有名称的单行,就像所有名称都在那里连接而不是每个名字对应一行:&lt;xsl:for-each select="$equipment"&gt; &lt;xsl:variable name="category" select="category"/&gt; &lt;fo:block&gt; &lt;xsl:text&gt;- &lt;/xsl:text&gt; &lt;xsl:value-of select="$category" /&gt; &lt;/fo:block&gt; &lt;/xsl:for-each&gt;

以上是关于XSL - 在变量中存储唯一和排序的数据的主要内容,如果未能解决你的问题,请参考以下文章

XSLT - 创建一个应该包含唯一和排序数据的变量

Google Charts - 在javascript中将数据作为变量传递

xslt正则表达式

使用 xsl:number 递减变量计数器

xslt中count属性的范围是多少?

数据存储-1MySQL 索引使用的注意事项