我正在寻找一种方法,根据给定数组/列表中的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操作数组的建议。
答案 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>