我可以这样做,但不能用于默认命名空间,<xsl:namespace>.如果我尝试为默认命名空间执行此操作:
<xsl:namespace name="" select"myUri"/>
Run Code Online (Sandbox Code Playgroud)
它永远不会奏效.它要求我明确定义元素的名称空间,以便能够使用上面的空前缀声明.
我想要这个的原因是因为我有一个任务是将输入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>
Run Code Online (Sandbox Code Playgroud)
它几乎解决了这个问题.不幸的是,孩子们被变压器注入""(空白)命名空间.如果我放一个子元素,这就是我得到的:
<newRoot xmlns="my-computed-namespace">
<child xmlns=""> ...
</child>
</newRoot>
Run Code Online (Sandbox Code Playgroud)
为什么变压器会把它xmlns=""放在孩子身上?如果我可以阻止这个,那么我找到了我的解决方案.
除了提供精确答案的@Tomalak之外,请注意<xsl:namespace>不要创建XSLT处理器通常使用所有元素或属性的名称空间声明.
目的<xsl:namespace>是创建特定的命名空间节点.此节点仅具有有限范围:当前元素或属性以及当前节点的所有子节点(如果它们未将前缀重新分配给另一个名称空间-ur).
<xsl:namespace>仅当我们想要为必须动态生成的名称空间uri动态创建名称空间时才需要使用(在转换开始时不是静态地知道).这种情况非常罕见.
在所有情况下,当静态地知道所需的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值内容中使用的命名空间 ".
如果需要这样的结果,解决方案是使用第二遍并将属于"无命名空间"的任何元素转换为所需的新命名空间.
这是在第二遍中使用的转换(两个通道可以组合成一个样式表/转换):
<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>
Run Code Online (Sandbox Code Playgroud)
将以上转换应用于以下示例(pass-1-result)xml文档时:
<a>
<b>
<c/>
</b>
</a>
Run Code Online (Sandbox Code Playgroud)
产生了期望的结果:
<a xmlns="my:Url">
<b>
<c/>
</b>
</a>
Run Code Online (Sandbox Code Playgroud)