【问题标题】:Namespace result in xsl:result-document appears on children instead of parent elementxsl:result-document 中的命名空间结果出现在子元素上而不是父元素上
【发布时间】:2017-07-17 21:40:03
【问题描述】:

我和许多人一样,在理解如何控制 xslt 输出中的某些 xslt 命名空间声明时遇到了困难。我在 Java 中使用最新版本的 Saxon XSLT 2.0 处理器。我能够找到解决<xsl:output> 命名空间声明时遇到的大多数问题的解决方案,但我遇到了<xsl:result-document> 命名空间声明的问题。我正在使用 XSL 创建部分 epub3 文件。

以下是我的 XSLT 2.0 文件的相关部分

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
xmlns="http://www.w3.org/1999/xhtml" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
xmlns:epub="http://www.idpf.org/2007/opf"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:my="my:functions" 
exclude-result-prefixes="xs xsl dc epub my"
version="2.0">
<xsl:output name="xhtml" method="xhtml" indent="yes"/>
<xsl:output name="xml" method="xml" indent="no"/>
<!--content.opf -->
<xsl:result-document href="{concat('ePubs/ePub',project/bookAbbrev,'/OEBPS/content.opf')}" format="xml" indent="yes">
<package xmlns="http://www.idpf.org/2007/opf" version="3.0"  xml:lang="en" unique-identifier="pub-identifier">

<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:identifier id="pub-identifier">temporary-<xsl:value-of select="/project/bookAbbrev"/>1</dc:identifier>
    <dc:title><xsl:value-of select="/project/bookTitle"/>-v1</dc:title>
    <dc:language>en</dc:language>
    <dc:creator id="creator">MDB</dc:creator>
    <dc:subject>history</dc:subject>
    <dc:date>2017-06-26</dc:date>
    <meta name="cover" content="cover-image"/>
    <meta property="dcterms:modified"><xsl:value-of select="format-dateTime(current-dateTime(),'[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01]Z')"/> </meta>
</metadata>
</package>
</xsl:result-document>
<!-- end content.opf -->
</xsl:stylesheet>

我没有包含 XML 文件,因为我认为在本示例中不需要它。我还删除了其他结果文档部分。

此 .opf 文件的所需输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf"
     version="3.0"
     xml:lang="en"
     unique-identifier="pub-identifier">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:identifier" id="pub-identifier">temporary-WB-A1</dc:identifier>
    <dc:title>Christian County Kentucky Will Book A-v1</dc:title>
    <dc:language>en</dc:language>
    <dc:creator id="creator">MDB</dc:creator>
    <dc:subject>history</dc:subject>
    <dc:date>2017-06-26</dc:date>
    <meta name="cover" content="cover-image"/>
    <meta property="dcterms:modified">2017-07-17T16:44:57Z</meta>
</metadata>
</package>

但不是 &lt;metadata&gt; 元素持有 xmlns:dc 命名空间声明,而是所有子元素都有 xmlns:dc 声明和父元素 no 声明,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf"
     version="3.0"
     xml:lang="en"
     unique-identifier="pub-identifier">
<metadata>
  <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/" id="pub-identifier">temporary-WB-A1</dc:identifier>
  <dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">Christian County Kentucky Will Book A-v1</dc:title>
  <dc:language xmlns:dc="http://purl.org/dc/elements/1.1/">en</dc:language>
  <dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/" id="creator">MDB</dc:creator>
  <dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/">history</dc:subject>
  <dc:date xmlns:dc="http://purl.org/dc/elements/1.1/">2017-06-26</dc:date>
  <meta name="cover" content="cover-image"/>
  <meta property="dcterms:modified">2017-07-17T16:44:57Z</meta>
</metadata>
</package>

任何帮助或解释将不胜感激。我已经多次搜索该论坛,但我认为我在其他帖子中找到的解决方案与这个问题并不完全相同。我希望我的问题中发布的信息足以说明问题。我是具有 XSL 经验的中级新手,因此可能使用了一些不恰当的术语。 谢谢 - 迈克尔

【问题讨论】:

  • 如果从xsl:stylesheetelement 中删除xmlns:dc="http://purl.org/dc/elements/1.1/" 声明会怎样?
  • 我确实尝试过,并从 Saxon XSLT 2.0 处理器Error at xsl:stylesheet on line 9 column 16 of DB-WB-CO-epubText-split.xsl: XTSE0808: Namespace prefix dc is not declared Stylesheet compilation failed: 1 error reported得到以下错误消息@
  • 我们需要一个小而完整的例子——最好是没有xsl:result-document(和xml:template)的例子。 -- FWIW,你得到的输出和你想要的输出之间的区别纯粹是装饰性的。
  • 迈克尔,感谢您的评论。我发布的代码来自我的工作样式表。我只删除了所有其他创建附加文件的结果文档部分。此特定部分仅从 XML 文件中读取几个值。如果这样会更好,我可以用设置文本替换 xsl:value-of 调用。样式表中没有其他模板被调用。您可能是正确的,它不重要,但我正在尝试匹配我在参考 epub3 文档中找到的格式。谢谢,迈克尔
  • 嗯,有些东西不适合这里,因为从 xsl:stylesheet 元素中删除 xmlns:dc="http://purl.org/dc/elements/1.1/" 声明不应该产生错误:声明在 metadata 元素中重复,我不'没有看到它在这个范围之外的任何地方被使用。

标签: xslt xslt-2.0


【解决方案1】:

您想要的输出在实际上不需要的元素上有一个命名空间声明。没关系;但要实现这一点,您需要了解命名空间如何隐式添加到元素的规则。

该元素是使用文字结果元素构造的。文字结果元素的规则是它们具有样式表中 LRE 范围内的所有名称空间的副本,排除的名称空间除外。在您的情况下, dc 是一个排除的命名空间,因为它出现在 exclude-result-prefixes 属性的值中。

如果你想为包元素而不是元数据元素排除这个命名空间,有几个选项可用:

(a) 避免在xsl:stylesheet 级别声明命名空间;只在需要的地方声明它

(b) 在文字结果元素上本地使用xsl:exclude-result-prefixes 属性,而不是(或以及)xsl:stylesheet 元素上。但是,这将需要对您的代码进行一些重组,因为该值是累积的:如果一个样式表元素上排除了前缀,则其子元素和后代元素会自动排除该前缀。您必须将 package 元素的构造移动到命名模板中,这样它就不会在词法上包含在 metadata 文字结果元素中。

(c) 使用xsl:namespace 指令将命名空间显式添加到package 元素。

(d) 使用 xsl:element 而不是使用 LRE 构造 metadata 元素,然后从排除的结果前缀列表中删除“dc”(exclude-result-prefixes 仅适用于使用 LRE 创建的元素)。

我认为最简单的解决方案是 (a)。除非在您的真实样式表中存在此示例未公开的内容,否则不需要在样式表级别声明 dc 命名空间。

请注意,这与xsl:result-document 的使用无关。

【讨论】:

  • 先生。凯,谢谢你的详细回复。按照您和 Michael 的建议,在删除 xmlns:dc 声明后,我得到了现在需要的结果。删除后的错误一定是由于我之后未能从 exlude-result-prefixes 中删除 dc 值。即使受益于您的几本书,以及我从 Ken Holman 和 Dimitri Novatchev 那里观看的视频系列,我仍然在为命名空间概念而苦恼。谢谢,迈克尔
  • 是的,命名空间的复杂性是可怕的(我曾经说过设计太糟糕了,没有人会使用它们)。但实际上,一旦你掌握了 XDM 树中命名空间节点的抽象,理解其中的规则就不难了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-11
  • 1970-01-01
  • 2019-12-22
  • 2021-09-23
  • 1970-01-01
相关资源
最近更新 更多