xsl:result-document中的命名空间结果显示在子元素而不是父元素上

时间:2017-07-17 21:40:04

标签: xslt xslt-2.0

我和许多人一样,无法理解如何在xslt ouput中控制一些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>

但是,不是持有 xmlns:dc 命名空间声明的<metadata>元素,而是所有子节点都有 xmlns:dc 声明,而父节点没有声明为如下:

<?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经验,因此可能使用了一些不恰当的术语。 谢谢 - 迈克尔

1 个答案:

答案 0 :(得分:2)

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

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

如果要为package元素排除此命名空间而不是元数据元素,可以使用以下几个选项:

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

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

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

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

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

请注意,这与xsl:result-document

的使用无关