【问题标题】:Transform attribute in commented out xml注释掉 xml 中的转换属性
【发布时间】:2017-08-02 15:50:18
【问题描述】:

我想转换一条我知道是有效 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>

我怀疑节点集函数实际上并没有像我想象的那样做。

非常感谢任何帮助。

【问题讨论】:

  • 您需要使用 XSLT 3.0 和 parse-xml 开始,然后您还需要解释结果是否应该包含 foo 元素节点或再次包含注释。在后一种情况下,您还需要 XSLT 3.0 中的 serialize 函数。

标签: xml xslt exslt


【解决方案1】:

要在 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 确实使这两种转换都变得更容易。不过,这个问题的正确解决方案还是在于原始文档的作者。

【讨论】:

  • 即使使用第二个 XSLT 对其进行处理,您仍然不会将修改后的元素作为注释,除非您可以使用 DOE 输出 &lt;!--,但我不确定这是否可行。
  • @Flynn1179 我不确定这是一个要求。
【解决方案2】:

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

您可以通过字符串操作来操作注释的值,这里可能已经有 100 个在 XSL 中替换文本中的值的示例了。

这里有你的具体例子,你可以做translate($xml-string,'x','y'),但我怀疑你真正的问题比这更复杂!

【讨论】:

  • 您正在考虑 XSLT 3.0。在 XSLT 2.0 中你不能这样做——至少不能直接或没有扩展。
  • 是的,我后来意识到,不记得这些是在什么时候添加的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-08
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 2019-08-03
相关资源
最近更新 更多