从列表中挑选元素

时间:2014-10-14 18:58:10

标签: xml xslt xslt-2.0

我需要将包含序列化逗号分隔列表的元素转换为单独的XML元素,选择具有特定前缀的列表元素。结果列表的第一个组件应作为与其他组件不同的元素输出。 例如,

<source>xxx-22-33, aa-11-11, aa-22-22, aa-33-33</source>

应该转化为

<ref>aa-11-11</ref>
<xref>aa-22-22</xref>
<xref>aa-33-33<xref>

我提出了以下模板以获得部分解决方案但是却难以接受特定治疗的第一个列表元素。有什么建议? TIA。

    <xsl:template name="xrefs">
        <xsl:param name="list"/>
        <xsl:for-each select="tokenize($list, ', ')">
            <xsl:variable name="el" select="."/>
            <xsl:if test="starts-with($el, 'aa-')">
                <xsl:element name="cve-id">
                    <xsl:value-of select="$el"/>
                </xsl:element>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

1 个答案:

答案 0 :(得分:0)

您不会显示调用xrefs模板的模板定义。但我可以给你一个没有命名模板的解决方案,即一个完全独立的样式表。

样式表的有趣部分是:

<xsl:variable name="element-name" select="if (position() = 1) then 'ref' else 'xref'"/>

我们在条件结果中使用XPath 2.0的能力。变量定义必须位于for-each内,该source标记position()元素的文本内容,因为normalize-space()函数的评估取决于上下文。在这种情况下,我们需要将上下文作为其中一个令牌。

我正在进一步将<?xml version="1.0" encoding="UTF-8" ?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="xml" indent="yes" /> <xsl:template match="source"> <xsl:for-each select="tokenize(.,',')"> <xsl:variable name="element-name" select="if (position() = 1) then 'ref' else 'xref'"/> <xsl:element name="{$element-name}"> <xsl:value-of select="normalize-space(.)"/> </xsl:element> </xsl:for-each> </xsl:template> </xsl:transform> 应用于令牌,因为如果有任何空格将在令牌化后保留。


此外,值得注意的是,我的方法对数据的性质做出了具体的假设 - 您没有全面解释这些假设。特别是,我假设它始终是列表中第一个应该区别对待的标记,而不是将具有特定内容的标记处理为偶然的第一个项目(因为您尝试的解决方案似乎不知何故)表示)。

<强>样式表

<?xml version="1.0" encoding="UTF-8"?>
<ref>xxx-22-33</ref>
<xref>aa-11-11</xref>
<xref>aa-22-22</xref>
<xref>aa-33-33</xref>

XML输出

{{1}}