在XSLT中基于给定数组修改元素

时间:2016-04-19 15:25:20

标签: xslt

我正在寻找一种方法,根据给定数组/列表中的productID将元素内容更改为“是”。

状态可以是是/否(或未设置)。

源XML:

<xml>
<product>
<productId>111111</productId>
<available>No</available>
</product>
<product>
<productId>888888</productId>
<available>No</available>
</product>
<product>
<productId>666666</productId>
<available>No</available>
</product>
<product>
<productId>99999</productId>
<available>Yes</available>
</product>
<product>
<productId>333333</productId>
<available>Yes</available>
</product>
</xml>

以下是带有productID的示例数组:

111111,666666,99999

我希望实现这些productID的可用元素始终设置为“是”。不在列表中的产品不应在输出中更改。

示例输出:

<xml>
<product>
<productId>111111</productId>
<available>Yes</available>
</product>
<product>
<productId>888888</productId>
<available>No</available>
</product>
<product>
<productId>666666</productId>
<available>Yes</available>
</product>
<product>
<productId>99999</productId>
<available>Yes</available>
</product>
<product>
<productId>333333</productId>
<available>Yes</available>
</product>
</xml>

奖金问题:欢迎使用bash / php操作数组的建议。

2 个答案:

答案 0 :(得分:1)

以下内容应该:

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

    <xsl:output method="xml" indent="yes" />

    <xsl:param name="available" select="'111111,666666,99999'" />

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="product/available">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test ="contains( concat(',',$available, ','),
                                            concat(',',../productId, ',') )">
                    <xsl:text>yes</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

这两个concat并不是必须的,但是为了避免因为在较长的一个中匹配较短的id而避免得失败的良好做法。 这将产生这个输出:

<xml>
    <product>
        <productId>111111</productId>
        <available>yes</available>
    </product>
    <product>
        <productId>888888</productId>
        <available>No</available>
    </product>
    <product>
        <productId>666666</productId>
        <available>yes</available>
    </product>
    <product>
        <productId>99999</productId>
        <available>yes</available>
    </product>
    <product>
        <productId>333333</productId>
        <available>Yes</available>
    </product>
</xml>

更改可用的参数取决于您的xslt处理器。例如,xsltproc支持stringparam:

--stringparam name value : pass a (parameter, UTF8 string value) pair

因此你可以称之为:

 xsltproc --stringparam available "888888" test.xsl in.xml

答案 1 :(得分:1)

对于未来,这是@MartinHonnen的XSLT 2.0版本:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

     <!-- .test: 111111,888888,99999,666666 -->
    <xsl:variable name="available" select="unparsed-text('.test')"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>

        </xsl:copy>
    </xsl:template>

    <xsl:variable name="ids" select="for $t in tokenize($available, ',') return normalize-space($t)"/>
        <xsl:template match="product[productId = $ids]/available">
        <available>Yes</available>
    </xsl:template>

</xsl:stylesheet>