在注释掉的xml中转换属性

时间:2017-08-02 15:50:18

标签: xml xslt exslt

我想转换一个我知道有效的xml的评论。例如,下面我想将bar属性的值从x更改为y。

<root><!-- <foo bar="x"/> --></root>

我创建的样式表位于

之下
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exslt="http://exslt.org/common">

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

    <xsl:template match="comment()">
        <xsl:comment>
            <xsl:variable name="xml-string">
                <xsl:value-of select="current()" />
            </xsl:variable>
            <xsl:variable name="xml-node" select="exslt:node-set($xml-string)" />
            <xsl:apply-templates select="$xml-node" />
        </xsl:comment>
    </xsl:template>

    <xsl:template match="@bar[parent::foo]">
        <xsl:attribute name="bar">
            <xsl:value-of select="'y'" />
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

但我得到的输出是

<?xml version="1.0" encoding="UTF-8"?><root><!-- <foo bar="x"/> --></root>

我怀疑节点集功能实际上并没有按照我的想法进行。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

要在XSLT 1.0或2.0中执行此操作,不使用任何扩展函数,您必须分两步执行此操作:

首先,将以下样式表应用于输入XML:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="comment()">
    <xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>

</xsl:stylesheet>

并将结果保存到文件中。然后使用第二个XSLT处理生成的文件。

请注意,并非所有处理器都支持disable-output-escaping

加了:

需要说的是,你这是一个傻瓜的差事。一旦你注释掉了XML,它就不再是XML了,如果没有一些重大的跳跃,就无法进行处理。

同样,如果您希望结果在处理后成为包含原始“XML”的注释,那么您正在查看另一个painful and complicated process

XSLT 3.0确实使转换更容易。仍然,这个问题的正确解决方案在于原始文档的作者。

答案 1 :(得分:1)

评论的内容不被视为XML-您是对的,节点设置功能不会这样做。如果你真的想这样做,你需要从XSLT3解析和序列化函数。

您可以使用字符串操作来操纵注释的值,这里可能有100个替换XSL中的文本值的示例。

根据您的具体示例,您可以translate($xml-string,'x','y'),但我怀疑您的真正问题比这更复杂!