我有一个复制xml文件的xsl并重命名根标记。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version = '1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:abc="http://example.com">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<test>
<xsl:apply-templates select="node()|@*"/>
</test>
</xsl:template>
<!--xsl:template match="abc:set">
-<xsl:apply-templates select="node()|@*"/>-
</xsl:template-->
</xsl:stylesheet>
这很好但是当我取消注释最后一个块来处理一些命名空间标签时,我得到一个错误,表示复制语句有问题。如何匹配和转换命名空间标签?
答案 0 :(得分:2)
我不知道你到底想要达到的目标。你的问题有点抽象。但是您的匹配属性是正确的。但是现在对于什么没有区别:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
确实如此:
<xsl:template match="abc:set">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>
一样。如果您只想复制所有内容,那么第一个模板就足够了,包括带有命名空间的标签。否则我猜你在匹配你的命名空间标签时需要做些不同的事情。如果是这样,那么您不需要再次调用身份匹配模板。例如:
<!--Do something with abc:set-->
<xsl:template match="abc:set">
<setchanged name="{@name}"/>
</xsl:template>
请放心,这将匹配所有abc:set标记并将转换应用于它们。
答案 1 :(得分:2)
您可能会收到错误,因为abc:set
元素具有属性,而abc:set
上的模板匹配正在生成未附加到元素的“裸”属性。
由于您没有在abc:set
的模板匹配中复制abc:set
元素(或创建元素),因此当该模板内的apply-templates
将模板应用于所选{时{1}}和abc:set/@*
,然后属性与身份模板匹配,并将被向前复制。
您可以通过从abc:set/node()
的select语句中取出@*
来验证是否存在问题,如下所示:
apply-templates
上面的模板只会处理<xsl:template match="abc:set">
<xsl:apply-templates select="node()"/>
</xsl:template>
的子节点。
如果您的目的是简单地复制abc:set
,那么您不需要在该元素上匹配特定模板。身份模板将匹配并为您处理。
答案 2 :(得分:2)
如果您确实要删除abc:set
元素,但保留其所属的子树,则替换:
<xsl:template match="abc:set">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>
<强>与强>:
<xsl:template match="abc:set">
<xsl:apply-templates/>
</xsl:template>
如果匹配的元素具有属性,则原始代码会导致错误,因为身份规则将复制它们,可能不会创建元素,因此这将尝试生成属于无元素的属性。在这种情况下,任何XSLT处理器都必须发出错误信号。
替换代码不处理匹配的abc:set
元素的任何属性。