带有内联 XSLT 的 XML

标签 xml xslt

我需要一个 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/

相关文章:

sql - 通过 SQL 使用 WHERE 子句查询 XML 子节点

java - 将 SOAP 字符串消息转换为 SoapMessage 时出现 NullPointer 异常

c# - Linq to Object/XML 其中元素不存在

javascript - 使voiceXML读取服务器返回的结果

java - 使用 XSLT 复制 XML 时绕过命名空间

html - 元素名称 gcse :searchbox-only cannot be represented as XML 1. 0

xml - Xslt:将节点添加到根元素

xslt - 如何为 XSLT 尚不可用的函数编写回退代码?

java - 添加 xml-stylesheet 并获得 standalone = yes

html - 使用 XSL 解析 XML 中的标记