3

我有一组使用 XSL 转换处理的 XML 文件。它们有一个默认命名空间,所以我的 XSL 转换必须包含以下声明:

xpath-default-namespace="urn:CZ-RVV-IS-VaV-XML-NS:data-1.2.2"

问题是这个值不时变化,我的转换突然停止工作,直到我从新文件中查看一个示例,提取这个命名空间 ID 并将其放入转换中,从而转换停止对旧文件工作。有没有办法将它作为参数传递,或者在运行时以某种方式设置它?我已经尝试过在各种教程中查找的参数语法,但没有一个适用于这种特殊用途。

我搜索了各种论坛,找到了对 XSL 的命名空间无关编码的引用,但不知道如何去做。Ian Williams 的“XSLT 和 Xpath”一书指出,必须声明默认命名空间,否则您在输出流中将一无所获,这对我来说就是这样。但我真的不想定期手动更改它,我想给用户一些可以工作的东西,而不需要我经常关注。

到目前为止,我发明的唯一 100% 可靠的方法是使用标准编程语言将 XML 源和 XSL 转换作为文本文件打开,从 XML 源中提取 URI,将其粘贴到 XSL 转换中,关闭这两个文件并然后,最后运行实际的变换。这行得通,但非常愚蠢,至少在我看来。如何更好地处理更改默认命名空间?

皮特

4

2 回答 2

5

xpath-default-namespace 的值必须是静态 URI,因此如果您希望样式表发生变化,则必须对样式表进行预处理。一种方法是使用 XSLT。每次将以下元样式表应用于您的主样式表,然后调用预处理结果。

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- Pass in the new namespace URI as a stylesheet parameter -->
  <xsl:param name="new-uri" required="yes"/>

  <!-- By default, copy everything as is -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- But update the value of @xpath-default-namespace -->
  <xsl:template match="@xpath-default-namespace">
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
      <xsl:value-of select="$new-uri"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

不过,这是一个有点奇怪的用例,因为命名空间并没有真正设计成如此动态。它们旨在限定名称,即构成名称的一部分。当你这样看时,动态命名空间没有多大意义。想象一个数据库,其表名和字段名每隔一段时间就会任意更改,迫使您重写所有 SQL 脚本以跟上更改。这就是类似的情况。

于 2009-12-07T20:56:35.507 回答
0

您是否尝试过定义样式表参数<xsl:param name="xpdn"/>并在样式表声明或顶级模板声明中使用它,如

<xsl:template match="...." xpath-default-namespace="$xpdn">

我在规范中找不到任何说这不起作用的东西(但我现在无法尝试)。

于 2009-12-07T20:50:07.873 回答