0

所以这是最近几天一直困扰我的问题。这应该相当容易,但是 XSLT 调试起来实在是太痛苦了。我们在 java 1.6 上使用 Xalan 1.0

输入 XML

<?xml version="1.0" encoding="UTF-8"?>
<rfb2>
    <rfb2_item>
        <VALDATE>2011-10-23</VALDATE>
        <FUND_ID>300</FUND_ID>
        <SEC_ID>34567</SEC_ID>
    </rfb2_item>
    <rfb2_item>
        <VALDATE>2011-1-09</VALDATE>
        <FUND_ID>700</FUND_ID>
        <SEC_ID>13587</SEC_ID>
    </rfb2_item>
    <rfb2_item>
        <VALDATE>2011-3-09</VALDATE>
        <FUND_ID>200</FUND_ID>
        <SEC_ID>999334</SEC_ID>
    </rfb2_item>
<rfb2>

我们需要将 XML 转换为每个 rfb2_item 的逗号分隔值列表,因此样式表总是迭代 rfb2_item 节点。我们在样式表中使用一个参数来控制 rfb2_item (valdate,fund_id,sec_id) 的哪些元素将被输出,以及以什么顺序输出,例如

<xsl:param name="$outputElements" select="'VALDATE,FUND_ID'"/>
..outputs...

2011-10-23,300
2011-1-09,700
2011-3-09,200



<xsl:param name="$outputElements" select="'SEC_ID'"/>    
..outputs...

34567
13587
999334

特殊情况,如果 $outputElements 为 '*',只需按照元素在输入 xml 中出现的顺序输出元素

<xsl:param name="$outputElements" select="'*'"/>

..outputs...

2011-10-23,300,34567
2011-1-09,700,13587
2011-3-09,200,999334

所以,我的问题是我们如何编写一个模板来根据 $outputElements 参数创建所需的输出?一个工作的例子会很棒......

4

2 回答 2

1

是的,FailedDev 是对的。有人会为你写:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="text" />

    <xsl:param name="outputElements" select=" 'FUND_ID,SEC_ID,VALDATE' " />

    <xsl:template match="rfb2_item">

        <xsl:for-each select="*[contains($outputElements, local-name()) or $outputElements = '*']">
            <xsl:sort select="string-length(substring-before($outputElements, local-name(.)))" />
            <xsl:value-of select="text()" />
            <xsl:if test="position() != last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#13;&#10;</xsl:text>

    </xsl:template>

</xsl:stylesheet>

一点解释。将xsl:for-each选择当前中的每个元素,rfb2_item其中本地名称包含在outputElements参数中,或者outputElements参数是*(如果是这种情况,总是会产生 true)。然后它会根据在本地名称之前的子字符串的长度对它们进行排序outputElements。由于当名称稍后出现在该参数中时,此值会变得更高,这会导致根据您的参数进行排序。

示例: elementVALDATE将为函数产生FUND_ID,SEC_ID,而该substring-before函数又将产生 14 作为字符串长度。这比您得到的 8 高SEC_ID,这意味着该VALDATE值是在 之后排序的SEC_ID

在 之后xsl:sort,我们只是xsl:value-of用来输出元素值。您可能想在那里修剪多余的空白。最后,我们正在测试该位置是否不等于当前上下文中最后一个节点的位置(即排序xsl:for-each 的位置),如果是,则输出一个逗号。这样可以避免在最后一个值之后输出逗号。

我插入的换行符采用xsl:textWindows/DOS 约定。删除&#13;如果文件应该只使用换行符换行,而不是回车+换行。

请注意,这不会在您的 CSV 输出中转义逗号!我会把它留给你。如果在 XSLT/XPath 中证明太困难,那么研究使用扩展函数将这个任务委托给 Java可能会很有趣。

于 2011-11-09T19:04:41.743 回答
0

有时在这种情况下,值得研究使用 XSLT 生成或修改 XSLT 代码的可能性。您可以通过这种方式进一步进行参数化 - 例如控制输出哪些字段、如何排序、是否分组、选择哪些行的选择标准等。

于 2011-11-09T22:25:06.347 回答