我想转换一个我知道有效的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>
我怀疑节点集功能实际上并没有按照我的想法进行。
非常感谢任何帮助。
答案 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')
,但我怀疑您的真正问题比这更复杂!