改变 XML 源文件中的 xpath-default-namespace

发布于 2024-08-14 01:13:56 字数 595 浏览 7 评论 0原文

我有一组 XML 文件,正在使用 XSL 转换进行处理。它们有一个默认名称空间,因此我的 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 转换中,关闭这两个文件,然后然后,最后运行实际的转换。这可行,但非常愚蠢,至少对我来说是这样。如何更好地处理更改默认命名空间?

皮特

I have a set of XML files that I am processing with an XSL transform. They have a default namespace, so my XSL transform must contain the declaration:

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

The problem is that this value changes from time to time, and my transform suddenly stops working, until I look at an example from the new file, extract this namespace ID and put it in the transform, whereby the transform stops working for old files. Is there a way to pass this as a parameter, or set it somehow at runtime? I have tried the parameter syntaxes that I looked up in various tutorials, but none have worked for this particular use.

I have searched all sorts of forums and found references to namespace-agnostic coding of XSL, but not figured out how to do it. Ian Williams' book "XSLT and Xpath" states that the default namespace must be declared, or you get nothing in the output stream, which is how it has worked for me. But I really don't want to have to change this by hand regularly, I want to give the user something that will work, without needing constant attention from me.

The only 100% reliable way I have invented so far is to use a standard programming language to open both the XML source and XSL transform as text files, extract the URI from the XML source, paste it into the XSL transform, close both files and then, finally run the actual transform. This works, but is incredibly dorky, at least to my taste. How can I better deal with changing default namespaces?

Pete

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

缱绻入梦 2024-08-21 01:13:57

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 脚本以跟上更改。这就是类似的东西。

The value of xpath-default-namespace must be a static URI, so you'll have to pre-process the stylesheet if you want it to vary. One way to do that would be to use XSLT. Apply the following meta-stylesheet to your primary stylesheet each time, and then invoke the pre-processed result instead.

<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>

This is a bit of a strange use case though, because namespaces weren't really designed to be so dynamic. They were designed to qualify names, i.e. make up part of a name. When you look at it that way, dynamic namespaces don't make a lot of sense. Imagine a database whose table and field names arbitrarily changed every once in a while, forcing you to rewrite all your SQL scripts to keep up with the changes. That's what this is akin to.

您是否尝试过定义样式表参数 并在样式表声明或顶级模板声明中使用它,就像

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

我在规范中找不到任何内容 一样这表明这行不通(但我现在无法尝试)。

Have you tried defining a stylesheet parameter <xsl:param name="xpdn"/> and using it in the stylesheet declaration or top level template declaration as in

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

I can't find anything in the spec that says this won't work (but I'm not in a position to try it just now).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文