我需要一个 XML 文件在安装后根据一些参数进行更改。
例如:
<?xml ...?>
<root xmlns="...">
<!-- remove this element when PARAM_MODE=1 -->
<sometag />
<!-- remove this element when PARAM_MODE=2 -->
<sometag2 />
<someothertag />
</root>
最简单的方法是使用 XSLT 删除元素,但我希望将注释和 XSL 结合起来而不是重复。
有什么可以做到的吗?像这样:
<?xml ...?>
<root xmlns="..." xmlns:xsl="XSL_NAMESPACE">
<!-- XSL to remove this element when PARAM_MODE=1 -->
<xsl:remove the attribute if $PARAM_MODE=1 />
<sometag />
<!-- XSL to remove this element when PARAM_MODE=2 -->
<xsl:remove the attribute if $PARAM_MODE=2 />
<sometag2 />
<someothertag />
</root>
最佳答案
这个样式表:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="...">
<xsl:param name="PARAM_MODE" select="1"/>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="my:sometag">
<xsl:if test="$PARAM_MODE!=1">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
<xsl:template match="my:sometag2">
<xsl:if test="$PARAM_MODE!=2">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
有了这个输入:
<root xmlns="...">
<!-- remove this element when PARAM_MODE=1 -->
<sometag />
<!-- remove this element when PARAM_MODE=2 -->
<sometag2 />
<someothertag />
</root>
输出:
<root xmlns="...">
<!-- remove this element when PARAM_MODE=1 -->
<!-- remove this element when PARAM_MODE=2 -->
<sometag2></sometag2>
<someothertag></someothertag>
</root>
请注意,如果您想要简化语法,来自http://www.w3.org/TR/xslt#result-element-stylesheet :
A simplified syntax is allowed for stylesheets that consist of only a single template for the root node. The stylesheet may consist of just a literal result element (see 7.1.1 Literal Result Elements). Such a stylesheet is equivalent to a stylesheet with an xsl:stylesheet element containing a template rule containing the literal result element; the template rule has a match pattern of
/
.
因此,您可以添加元素,但不能删除它们。
编辑:简化语法的反向逻辑。
假设这个样式表有... test.xsl
URI:
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<root
xmlns="..."
xmlns:my="..."
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xsl:version="1.0">
<PARAM_MODE>1</PARAM_MODE>
<!-- remove this element when PARAM_MODE=1 -->
<xsl:if test="document('')/my:root/my:PARAM_MODE!=1">
<sometag />
</xsl:if>
<!-- remove this element when PARAM_MODE=2 -->
<xsl:if test="document('')/my:root/my:PARAM_MODE!=2">
<sometag2 />
</xsl:if>
<someothertag />
</root>
Runnig 以自身作为输入(我用 PI 强调这一点。另外,这使得 fn:document()
变得多余...),它输出:
<root xmlns="..." xmlns:my="...">
<PARAM_MODE>1</PARAM_MODE>
<sometag2 />
<someothertag />
</root>
最后,一个评论驱动的样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="PARAM_MODE" select="1"/>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[preceding-sibling::node()[1]
/self::comment()[starts-with(.,' remove ')]]">
<xsl:if test="$PARAM_MODE != substring-after(
preceding-sibling::comment()[1],
'PARAM_MODE=')">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出:
<root xmlns="...">
<!-- remove this element when PARAM_MODE=1 -->
<!-- remove this element when PARAM_MODE=2 -->
<sometag2></sometag2>
<someothertag></someothertag>
</root>
关于带有内联 XSLT 的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4034204/