将 XSLT 输入文档前缀映射到首选值

发布于 2024-09-11 12:31:32 字数 1496 浏览 6 评论 0原文

使用 XSLT,我想知道如何让输出使用样式表的名称空间前缀而不是输入文档的前缀。举例来说,给出这个非常简化的文档:

<?xml version="1.0"?>
<a:node xmlns:a="urn:schemas:blah:"/>

以及以下 XSL 转换:

<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:blah="urn:schemas:blah:" version="2.0">
   <xsl:output indent="yes">
   <xsl:template match="/blah:node">
      <xsl:copy/><!-- marked -->
   </xsl:template>
</xsl:transform>

我可以告诉处理器(Saxon8,如果重要的话)识别前缀 'blah:' 和 'a:' 的等价性,但是 fn:in-scope-prefixes() 不会不显示“blah”,仅显示“a”。将上面的 行更改为:

<node><xsl:value-of select="in-scope-prefixes(.)"/></node>

输出:

<?xml version="1.0" encoding="UTF-8"?>
<node xmlns:blah="urn:schemas:blah:">xml a</node>

如何在不事先知道输入文件调用该前缀的情况下将输入前缀 'a' 映射到 'blah' '一个'? (所以 对我不起作用。)

作为进一步的上下文,如果它指向更好的解决方案,那么这是为了查看外部生成的 XML 文档。外部进程使用自动生成的前缀“a:”、“b:”、“c:”等创建输入文档。我希望能够使用“友好”命名空间前缀显示这些前缀。

更新:in-scope-prefixes() 行为由 静态已知命名空间的定义

Using XSLT, I'm wondering how to get the output to use my stylesheet's namespace prefixes rather than the input document's prefixes. By way of example, given this very simplified document:

<?xml version="1.0"?>
<a:node xmlns:a="urn:schemas:blah:"/>

And the following XSL transform:

<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:blah="urn:schemas:blah:" version="2.0">
   <xsl:output indent="yes">
   <xsl:template match="/blah:node">
      <xsl:copy/><!-- marked -->
   </xsl:template>
</xsl:transform>

I can tell that the processor (Saxon8 if it matters) recognizes the equivalence of the prefixes 'blah:' and 'a:', but fn:in-scope-prefixes() for example doesn't show 'blah', only 'a'. Changing the <!-- marked --> line above to:

<node><xsl:value-of select="in-scope-prefixes(.)"/></node>

Outputs:

<?xml version="1.0" encoding="UTF-8"?>
<node xmlns:blah="urn:schemas:blah:">xml a</node>

How can I map the input prefix 'a' to 'blah' without knowing in advance that the input file calls that prefix 'a'? (So <xsl:namespace-alias/> won't work for me.)

As further context, if it points toward a better solution, this is for viewing XML documents that are generated externally. The external process creates the input document using automatically-generated prefixes 'a:', 'b:', 'c:', etc. I want to be able to display those prefixes using 'friendlier' namespace prefixes.

Update: The in-scope-prefixes() behavior is explained by the definition of Statically known namespaces

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

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

发布评论

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

评论(3

方觉久 2024-09-18 12:31:32

此转换在 XSLT 1.0 和 XSLT 2.0 中均如此(只需更改 version 属性)):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my"
 >
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <my:namespaces>
    <ns prefix="blah" uri="urn:schemas:blah:"/>
    <ns prefix="foo" uri="uff:anotherNamespace"/>
  </my:namespaces>

  <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "*[namespace-uri()=document('')/*/my:namespaces/*/@uri]">
  <xsl:variable name="vNS" select=
  "document('')/*/my:namespaces/*
                   [@uri=namespace-uri(current())]"/>
  <xsl:element name="{$vNS/@prefix}:{local-name()}"
       namespace="{namespace-uri()}">
   <xsl:copy-of select=
    "namespace::*[not(. = namespace-uri(current()))]"/>
   <xsl:copy-of select="@*"/>
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

复制任何 XML 文档并仅替换此前缀文档用于选择具有我们指定的前缀的命名空间。

应用于此 XML 文档时

<t>
    <a:node xmlns:a="urn:schemas:blah:"/>
    <b:node xmlns:b="urn:schemas:blah:"/>
    <c:node xmlns:c="uff:anotherNamespace"/>
</t>

生成所需结果

<t>
   <blah:node xmlns:blah="urn:schemas:blah:"/>
   <blah:node xmlns:blah="urn:schemas:blah:"/>
   <foo:node xmlns:foo="uff:anotherNamespace"/>
</t>

This transformation (both in XSLT 1.0 and XSLT 2.0 (just change the version attribute)) :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my"
 >
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <my:namespaces>
    <ns prefix="blah" uri="urn:schemas:blah:"/>
    <ns prefix="foo" uri="uff:anotherNamespace"/>
  </my:namespaces>

  <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "*[namespace-uri()=document('')/*/my:namespaces/*/@uri]">
  <xsl:variable name="vNS" select=
  "document('')/*/my:namespaces/*
                   [@uri=namespace-uri(current())]"/>
  <xsl:element name="{$vNS/@prefix}:{local-name()}"
       namespace="{namespace-uri()}">
   <xsl:copy-of select=
    "namespace::*[not(. = namespace-uri(current()))]"/>
   <xsl:copy-of select="@*"/>
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

Copies any XML document and only replaces the prefixes this document uses for select namespaces with the prefixes we have specified.

when applied on this XML document:

<t>
    <a:node xmlns:a="urn:schemas:blah:"/>
    <b:node xmlns:b="urn:schemas:blah:"/>
    <c:node xmlns:c="uff:anotherNamespace"/>
</t>

the wanted result is produced:

<t>
   <blah:node xmlns:blah="urn:schemas:blah:"/>
   <blah:node xmlns:blah="urn:schemas:blah:"/>
   <foo:node xmlns:foo="uff:anotherNamespace"/>
</t>
小女人ら 2024-09-18 12:31:32

身份转换加上这个模板怎么样:

<xsl:template match="blah:*">
  <xsl:element name="blah:{local-name()}">
    <xsl:apply-templates select="*|@*" />
  </xsl:element>
</xsl:template>

我不确定这是否是 XSLT 2.0 中最优雅的方法,但它确实有效。

How about the identity transform plus this template:

<xsl:template match="blah:*">
  <xsl:element name="blah:{local-name()}">
    <xsl:apply-templates select="*|@*" />
  </xsl:element>
</xsl:template>

I'm not certain that this is the most elegant way to do it in XSLT 2.0, but it works.

烙印 2024-09-18 12:31:32

查看 顶级元素的规范。我相信它会实现你想要的。

Take a look at the specification for the <xsl:namespace-alias ...> top-level element. I believe it will accomplish what you want.

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