XSLT中的别名前缀(而不是命名空间)



我想将输出中的前缀从样式表本身的前缀更改为前缀。

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>

你应该做好一切准备。

最新更新