我正在尝试过滤掉元素,并重命名元素值,但我无法让它工作:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:template match="xml">
<xsl:copy>
<xsl:for-each select="product[matches(code, 'C17.*[^V]$')]">
<xsl:copy>
<xsl:copy-of select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="title">
<xsl:copy>
<xsl:value-of select="replace(.,'Apple','Carrot')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
示例输入数据:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<product>
<code>C17020</code>
<title>Apple</title>
</product>
<product>
<code>C1723V</code>
<title>Samsung</title>
</product>
</xml>
我想离开<product>
从C17开始,但不以V结尾。我使用C17.*[^V]$
正则表达式。这部分正在运作。
问题在于重命名标题功能。如果我将此步骤添加到具有代码的新XSLT:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
在开始时,它的工作原理。
我在这里做错了什么?
答案 0 :(得分:3)
问题是您在匹配<xsl:copy-of select="@*|node()"/>
的模板中正在进行xml
。这将复制属性和子节点,购买不会应用任何模板。因此,您的模板匹配title
尚未使用。
您需要在此使用xsl:apply-templates
,但也要包含身份模板(您在新的XSLT代码中使用的模板),以确保code
也被复制
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xml">
<xsl:copy>
<xsl:for-each select="product[matches(code, 'C17.*[^V]$')]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="title">
<xsl:copy>
<xsl:value-of select="replace(.,'Apple','Carrot')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
注意,您实际上可以简化您的XSLT。通过使用身份模板,您可以使用模板删除您不想复制的内容,而不是明确要复制的内容....
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="product[not(matches(code, 'C17.*[^V]$'))]" />
<xsl:template match="title">
<xsl:copy>
<xsl:value-of select="replace(.,'Apple','Carrot')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
需要注意的另一件事是matches
和replace
仅适用于XSLT 2.0。