【问题标题】:How to specify default namespace for <xsl:element ...> productions?如何为 <xsl:element ...> 作品指定默认命名空间?
【发布时间】:2017-02-22 13:11:41
【问题描述】:

我有一个带有未命名命名空间的 XML,这样想:

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="<see below>" ?>
<root>
    <child>Hello</child>
</root>

我打算用 XSLT 将其转换为 X(HT)ML 树。我想摆脱的一些事情是:

  1. 不要在转换样式表(如下)中使用“xsl:”前缀。这是为了简洁,尽管我记住我可能会为减少输入我的 XSL 代码而付出代价,而在输入其他所有内容时会更加冗长。无论如何,我想看看它是如何只使用无前缀的 XSL 语法来实现的。

  2. 我将 HTML 输出为 XHTML(因此扩展为符合 XML)树。不是文本,也不是“HTML 文本”——输出方法是“xml”。这是为了让用户代理不必解析 [HTML] 文本。

  3. 我想使用 XSL element 元素来生成结果树。不输入“”。

基本上,我想看看如何进行通用 XML->XML 转换,其中生成的树是 XHTML 节点或文档,与 HTML 5 兼容。

未完成简化形式的 XSL 样式表文件:

<?xml version="1.0" encoding="utf-8" ?>
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform">
    <output method="xml" />
    <template match="/">
        <element name="h1">
            <text>Hello World.</text>
        </element>
    </template>
</stylesheet>

我打算将 HTML 的 htmlbody 元素作为 h1 的祖先元素,并实际转换源节点。但是这个例子应该足以说明我即将面临的问题——我希望结果树中的h1 元素属于其合法的XHTML 名称空间。如果没有通过namespace 属性对element 节点进行显式命名空间声明,用户代理似乎会将其解释为名称为h1 的未知节点。很公平,我猜。

我不想做的是将namespace="http://www.w3.org/1999/xhtml" 添加到element XSL 元素的每个实例中,显然我可能有几十个。可悲的是,这目前看起来是我唯一的选择。假设我使用 XSL 命名空间作为样式表文档的默认命名空间,我能否以某种方式暗示生成的树元素默认属于 XHTML 命名空间?

我知道我的变态极端情况可能是大多数人明确使用xsl: 前缀的原因,但我想避免它,毕竟 XSL 是文档的命名空间。但如果是 XSLT 1.0 的限制,那我就认输了。

XML 由 Firefox 48 转换和呈现。

【问题讨论】:

  • 转换的预期输出是什么?
  • 就像我说的,一个 XHTML 节点树。由一个或多个 XHTML 元素组成。
  • 恐怕你的假设'输出方法是“xml”。这是为了让用户代理不必解析 [HTML] 文本'并不是真正有意义的,在浏览器世界中,Firefox 或 Seamonkey 等 Mozilla 浏览器确实会创建一个结果树并呈现它,无论您是否有输出方法htmlxml,而其他实现将XSLT 转换的序列化结果提供给HTML 或XML 解析器,无论您使用输出方法html 还是xml 都很重要。由于您希望与 HTML5 兼容,我建议不要使用命名空间并使用输出方法 html
  • @MartinHonnen 好吧,他们肯定会创建一个结果树,在使用“xml”输出方法的情况下,我认为这就是创建树的原因,作为实际的 DOM 树,而不是首先生成文本然后解析它,当您通过 HTTP 或磁盘加载 HTML 文本文件时会发生这种情况。因此消除了解析阶段,因为 Firefox 通过应用 XSLT 生成树然后呈现它。您是否断言我正在以任何方式获取文本流?这当然是可能的,但你能证实这一说法吗?至于 HTML 5 命名空间,我发现 XHTML 在解析方面优于 HTML 5。
  • Firefox 创建并呈现 XSLT 转换的结果树,无论您使用输出方法 xml 还是 html。这就是为什么它在 XSLT 转换的 HTML 结果中根本不支持 disable-output-escaping 也不支持 Javascript document.write (请参阅developer.mozilla.org/en-US/docs/Web/API/XSLTProcessor/…,其中说“Mozilla 相反会呈现您的转换结果”和“禁用输出转义需要我们将解析步骤添加到我们的输出生成中,而我们没有。”。

标签: firefox xslt xhtml


【解决方案1】:

大多数人使用xsl: 前缀,因为这样做很方便。除其他外,它允许您将另一个命名空间定义为默认命名空间,从而避免需要显式地将命名空间添加到每个 element 指令和每个文字结果元素。

在您的示例中,您可以简单地将另一个前缀绑定到 XHTML 命名空间并使用它来代替完整的命名空间:

<stylesheet version="1.0" 
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.w3.org/1999/xhtml">
<output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<template match="/">
    <element name="x:h1">
        <text>Hello World.</text>
    </element>
</template>

</stylesheet>

或(同样的事情):

<stylesheet version="1.0" 
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.w3.org/1999/xhtml">
<output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<template match="/">
    <x:h1>
        <text>Hello World.</text>
    </x:h1>
</template>

</stylesheet>

还要注意默认命名空间是继承的。您可以在输出树的根级别将 XHML 命名空间声明为默认名称,并让其所有后代继承它。这里的问题是您的 XSLT 指令必须被排除在外:

<stylesheet version="1.0" 
xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<template match="/">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <body>
            <text xmlns="http://www.w3.org/1999/XSL/Transform">Hello World.</text>
        </body>
    </html>
</template>

</stylesheet>

希望现在您明白为什么使用诸如xsl: 之类的前缀是标准的。

【讨论】:

  • 谢谢,这几乎解释了我在这方面的一切。很高兴知道我想要的 is 是可能的,但没有为结果树指定一些默认命名空间,这可能是也可能不是一个好主意,就像你说的,这些解决方案说明了为什么 @ 987654327@ 前缀可能被认为是标准的。我选择了前缀,没有使用xsl:element(好吧,对于变量名元素,我认为无法避免)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 2011-02-21
相关资源
最近更新 更多