我可以这样做,但不是默认命名空间,使用<xsl:namespace>.
如果我尝试为默认命名空间执行此操作:
<xsl:namespace name="" select"myUri"/>
它永远不会奏效。它要求我明确定义元素的名称空间,以便能够使用上面的空前缀声明 我想要这个的原因是因为我有一个任务是将输入XML文件转换为另一个输出xml。输出XML有很多元素,我不想为每个元素显式设置名称空间。这就是为什么我想设置默认值而不再打扰。但必须根据源XML中的某些数据计算默认值。它在整个转换期间不会改变,但它依赖于输入XML数据。 有解决方案吗
编辑1: 支持:
<xsl:namespace>
,我就无法为它创建默认命名空间,只能为前缀命名空间。即使使用前缀,也不会传播给孩子。编辑2: dkackman建议:
<xsl:template match="root">
<xsl:param name ="ns">my-computed-namespace</xsl:param>
<xsl:element name="newRoot" namespace="{$ns}"/>
</xsl:template>
它几乎解决了这个问题。不幸的是,孩子们被变压器注入“”(空白)命名空间。如果我放置一个子元素,这就是我得到的:
<newRoot xmlns="my-computed-namespace">
<child xmlns=""> ...
</child>
</newRoot>
为什么变压器会将这个xmlns=""
放在孩子身上?如果我可以阻止这一点,那么我找到了解决办法。
答案 0 :(得分:7)
除了提供准确答案的@Tomalak之外,请注意<xsl:namespace>
并非旨在创建一个名称空间声明,供XSLT处理器使用所有元素或属性。
<xsl:namespace>
的目的是创建一个特定的命名空间节点。此节点仅具有有限的范围:当前元素或属性,以及当前节点的所有子节点,如果它们不将前缀重新分配给另一个名称空间-uri。
只有当我们想要为必须动态生成的namespace-uri动态创建名称空间时才需要使用<xsl:namespace>
(在转换开始时不是静态地知道)。这种情况非常罕见。
在所有情况下,如果静态地知道所需的namspace-uri,只需将此命名空间声明为适当的可见性级别(通常在<xsl:stylesheet>
指令处)然后只需使用关联的前缀,必须使用此命名空间的任何地方。
<强>更新强>
我刚刚在另一个论坛的专家对话中证实,<xsl:namespace>
无法做到这一点。它为当前元素添加了一个没有名称的命名空间节点,但是文字结果元素以1:1的形式复制并保留在它们的(无)命名空间中。
以下是XSLT W3C WG编辑Michael Kay博士如何解释:
“您需要使用正确的展开名称创建元素和属性
你创造它们的时间。如果这意味着使用xsl:element
,那就这样吧。
xsl:namespace
只能用于为这些创建其他命名空间节点
为元素和中使用的前缀/ uris自动创建的
属性名称;它不能用于修改元素的名称或
属性节点。
与往常一样,要了解这一点,您需要了解数据模型
命名空间。元素/属性名称是三元组,包含(prefix, uri,
localname)
。命名空间节点是一对(prefix, uri)
。有一致性
规则如果存在包含prefix=P
uri=U
的元素或属性名称
那么必须有一个命名空间节点(P, U)
。名称空间修复过程
确保在创建时自动创建此命名空间节点
元素或属性。 xsl:namespace
允许您创建
其他命名空间节点,通常用于QName值中使用的命名空间
含量”。
如果需要这样的结果,解决方案是使用第二遍并将属于“no namespace”的任何元素转换为所需的新命名空间。
这是第二次传递中使用的转换(两次传递可以组合成一个样式表/转换):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vUrl" select="'my:Url'"/>
<xsl:template match="*[namespace-uri()='']">
<xsl:element name="{name()}" namespace="{$vUrl}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
对以下示例(pass-1-result)xml文档应用上述转换时:
<a>
<b>
<c/>
</b>
</a>
产生了所需的结果:
<a xmlns="my:Url">
<b>
<c/>
</b>
</a>
答案 1 :(得分:1)
简单:
<xsl:stylesheet
version="1.0"
xmlns:xsl="..."
xmlns="default output namespace for unprefixed elements"
>
<!-- ... -->
</xsl:stylesheet>
答案 2 :(得分:0)
试试这个:
<xsl:template match="root">
<xsl:param name ="ns">my-computed-namespace</xsl:param>
<xsl:element name="newRoot" namespace="{$ns}"/>
</xsl:template>
然后你可以这样称呼:
<xsl:apply-templates select="root">
<xsl:with-param name="ns" select="computationXPath"/>
</xsl:apply-templates>
修改强>
或者使用variable
代替param
:
<xsl:variable name ="ns">my-computed-namespace</xsl:variable>
<xsl:template match="root">
<xsl:element name="newRoot" namespace="{$ns}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
(无需调用模板with-param
)