我想将输出中的前缀从样式表本身的前缀更改为前缀。
XSLT文件:
<stylesheet version="1.0" xmlns:a="nsA">
<template match="/">
<a:out/>
</template>
</stylesheet>
我得到的:
<a:out xmlns:a="nsA" />
我想要什么:
<b:out xmlns:b="nsA" />
请注意,我只想更改前缀,而不是命名空间。元素名称空间别名将仅转换名称空间,保留前缀不变。
如果可以完全删除前缀,则可获得额外积分:
<out xmlns="nsA" />
请注意,XSLT元素没有前缀,输出元素有前缀。它必须保持这样。我知道这个问题可以通过对XSLT加前缀和取消对输出元素加前缀来解决,但这不是一个选项。要输出的元素必须具有样式表中提供的前缀,只有在输出中才能更改。
我得到的:
<a:out xmlns:a="nsA" />
不,这不是你得到的——至少不是你应该得到的。使用一个不错的XSLT处理器,您会收到一个错误,告诉您文档不是一个有效的样式表。
请注意,XSLT元素没有以为前缀
不知道你为什么想要这样(这类似于开枪打自己的腿),但如果你坚持,你可以为样式表定义一个默认的名称空间,并使用不固定的XSLT元素,例如:
<stylesheet version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform">
<template match="/">
<!-- ... -->
</template>
</stylesheet>
但是,在这种情况下,非XSLT元素必须加前缀或显式分配命名空间。
如果可以完全删除前缀,则可获得额外积分:
<out xmlns="nsA" />
如果这是你想要的,你为什么不写出来呢?
以下任意一种:
<stylesheet version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:a="nsA"
exclude-result-prefixes="a">
<template match="/">
<element name="out" namespace="nsA"/>
</template>
</stylesheet>
或者简单地说:
<stylesheet version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:a="nsA"
exclude-result-prefixes="a">
<template match="/">
<out xmlns="nsA"/>
</template>
</stylesheet>
将产生:
<?xml version="1.0" encoding="UTF-8"?>
<out xmlns="nsA"/>
请注意,xmlns:a="nsA"
声明仅用于寻址源XML文档中恰好位于同一"nsA"命名空间中的元素。否则,它是完全多余的。
XSLT1.0保留前缀选择实现定义;XSLT2.0要求,对于文本结果元素,输出中的前缀与样式表中的前缀相同。所以你被冲洗了。
当然,如果放宽限制,有很多方法可以解决你的问题。一个有趣的解决方案是在执行样式表之前对其进行转换;更普通的方法是变换输出作为后处理步骤。
也许是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="nsA"
xmlns:b="nsA">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="*">
<xsl:element name="b:{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
您显然在编写XSLT的限制范围内工作,但决定对我们保密(感谢您),所以我们只能猜测什么能满足您的要求。
如果:
- 您的XSLT引擎支持多种
node-set()
函数 - 您可以修改与文档根匹配的模板(如果还没有,则添加一个)
- 您可以添加新模板
然后以下内容应该适用于您请求的"奖励"版本。
添加以下模板(如果您已经有一个与文档根匹配的模板,请将该模板中的<apply-templates />
替换为原始模板的内容,然后删除原始模板):
<template match="/">
<variable name="result">
<apply-templates />
</variable>
<!-- If you're using something other than exslt to get the node-set
function, then use the namespace for that instead. -->
<apply-templates select="exslt:node-set($result)"
mode="fixupNamespace"
xmlns:exslt="http://exslt.org/common" />
</template>
添加这三个模板:
<template match="node() | @*" mode="fixupNamespace">
<copy>
<apply-templates select="node() | @*" mode="fixupNamespace" />
</copy>
</template>
<template match="*" mode="fixupNamespace">
<element name="{name()}" namespace="{namespace-uri()}">
<apply-templates select="node() | @*" mode="fixupNamespace" />
</element>
</template>
<template match="a:*" mode="fixupNamespace">
<element name="{local-name()}" namespace="nsA">
<apply-templates select="node() | @*" mode="fixupNamespace" />
</element>
</template>
你应该做好一切准备。