XSL编号同时使用两个不同的集合

时间:2018-01-06 00:19:45

标签: xml xslt

继我之前的问题和给定的解决方案XSL numbering at different levels ....

之后

上一个问题涉及使用XSL 3.0 / Saxon将“脚注”数字插入XML文本。提供的解决方案效果很好,如果远远高于我的理解能力。随着这些事情的发展,我实际上需要插入两种类型的脚注,一些使用数字(1,2,3),一些使用字母(a,b,c),具体取决于接收脚注编号/字母的元素。可在此处找到包含更新文件(包括错误输出)的修订沙箱:http://xsltfiddle.liberty-development.net/948Fn5a/6

我认为人们可以使用单独的模式“加倍”给定的解决方案,但是第二种模式appnotes没有做任何事情,似乎除了原始文本加倍! (有关结果,请参阅xsltfiddle沙箱)

示例XML:

<?xml version="1.0" encoding="utf-8" ?>
<corpus>
<deposition>
    <deposition-title>Praesent vitae</deposition-title>
    <text>
        <seg type="not_foo">Lorem ipsum dolor sit amet, consectetur 
            adipiscing elit. Vivamus<note2>another note 2</note2> ultrices consequat facilisis. 
            Suspendisse a odio<note>foo note</note> in lobortis. Aenean 
            non dui scelerisque, rutrum est at, cursus sem.</seg>
        <seg type="foo">Ut pharetra bibendum ipsum, portitor 
            velit pharetra quis. Aeneano<note>foo note</note> purus. Praesent 
            aliquam viverra tellus<note>another note</note> in condimentum.</seg>
    </text>
</deposition>
<deposition>
    <deposition-title>Elementum arcu non</deposition-title>
    <text>
        <seg type="foo">Curabitur pulvinar leo eget. Orci varius 
            natoque penatibus et magnis dis<note>foo note</note> montes, 
            nascetur ridiculus mus.</seg>
            <seg type="foo">Curabitur pulvinar leo eget. Orci varius 
            natoque penatibus<note2>another note 2</note2> et magnis dis<note>foo note</note> montes, 
            nascetur ridiculus mus.</seg>
        <seg type="not_foo">Morbi vehicula dolor bibendum enim mollis lobortis. 
            Nulla rutrum vel diam vel posuere. Aliquam pellentesque 
            malesuada elit sed tempor.</seg>
    </text>
</deposition>
<deposition>
    <deposition-title>Elementum arcu non</deposition-title>
    <text>
        <seg type="foo">Curabitur pulvinar leo eget. Orci varius 
            natoque penatibus et magnis dis<note>foo note</note> montes, 
            nascetur ridiculus mus.</seg>
        <seg type="not_foo">Morbi vehicula dolor bibendum enim mollis lobortis. 
            Nulla rutrum vel diam vel posuere. Aliquam<note2>another note 2</note2> pellentesque 
            malesuada elit sed tempor.</seg>
    </text>
</deposition>

XSL 3.0:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

<xsl:mode on-no-match="shallow-copy"/>

<xsl:mode name="add-footnotes" on-no-match="shallow-copy"/>

<xsl:mode name="add-appnotes" on-no-match="shallow-copy"/>

<xsl:variable name="footnotes">
  <xsl:apply-templates mode="add-footnotes"/>
</xsl:variable>

<xsl:variable name="appnotes">
  <xsl:apply-templates mode="add-appnotes"/>
</xsl:variable>

<xsl:template match="seg[@type = 'foo'] | note" mode="add-footnotes">
  <xsl:next-match/>
  <footnote/>
</xsl:template>

<xsl:template match="note2" mode="add-appnotes">
  <xsl:next-match/>
  <appnote/>
</xsl:template>

<xsl:template match="/">
  <xsl:apply-templates select="$footnotes/node() | $appnotes/node()"/>
</xsl:template>

<xsl:template match="footnote">
  <xsl:copy>
      <xsl:number level="any" format="1" from="deposition"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="appnote">
  <xsl:copy>
      <xsl:number level="any" format="a" from="deposition"/>
  </xsl:copy>
</xsl:template>

我的预期结果是元素seg[@type = 'foo'] | note现在跟<footnote>后面有1,2,3等,而元素note2后面跟着<appnote> a,b,c。但只有前者发生....同时加倍整个XML文档。再次看到上面链接的沙箱。

提前致谢。

1 个答案:

答案 0 :(得分:1)

如果你想用三个不同的步骤来解决这个问题,那么你需要确保第二步使用第一步的结果作为输入而不是原始输入,也就是说,你必须确保使用变量有点不同:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="xs math map array"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:mode name="add-footnotes" on-no-match="shallow-copy"/>

  <xsl:mode name="add-appnotes" on-no-match="shallow-copy"/>

  <xsl:variable name="footnotes">
      <xsl:apply-templates mode="add-footnotes"/>
  </xsl:variable>

  <xsl:variable name="appnotes">
      <xsl:apply-templates select="$footnotes/node()" mode="add-appnotes"/>
  </xsl:variable>

  <xsl:template match="seg[@type = 'foo'] | note" mode="add-footnotes">
      <xsl:next-match/>
      <footnote/>
  </xsl:template>

    <xsl:template match="note2" mode="add-appnotes">
      <xsl:next-match/>
      <appnote/>
  </xsl:template>

  <xsl:template match="/">
      <xsl:apply-templates select="$appnotes/node()"/>
  </xsl:template>

<xsl:template match="footnote">
      <xsl:copy>
          <xsl:number level="any" format="1" from="deposition"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="appnote">
      <xsl:copy>
          <xsl:number level="any" format="a" from="deposition"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

http://xsltfiddle.liberty-development.net/948Fn5a/7

我认为你不需要三个模式分别需要三个步骤,你可以简单地添加模板,创建appnote s到第一步/模式:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:mode name="add-notes" on-no-match="shallow-copy"/>

  <xsl:variable name="notes">
      <xsl:apply-templates mode="add-notes"/>
  </xsl:variable>

  <xsl:template match="seg[@type = 'foo'] | note" mode="add-notes">
      <xsl:next-match/>
      <footnote/>
  </xsl:template>

  <xsl:template match="note2" mode="add-notes">
      <xsl:next-match/>
      <appnote/>
  </xsl:template>

  <xsl:template match="/">
      <xsl:apply-templates select="$notes/node()"/>
  </xsl:template>

<xsl:template match="footnote">
      <xsl:copy>
          <xsl:number level="any" format="1" from="deposition"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="appnote">
      <xsl:copy>
          <xsl:number level="any" format="a" from="deposition"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

http://xsltfiddle.liberty-development.net/948Fn5a/8

作为该方法的变体,因为您只想转换deposition元素并且只需要对该子树中的其他元素进行编号,所以不使用全局变量可能更容易,更有效树转换但只转换deposition内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:mode name="add-notes" on-no-match="shallow-copy"/>

    <xsl:template match="deposition">
        <xsl:variable name="notes-added">
            <xsl:apply-templates mode="add-notes"/>
        </xsl:variable>
        <xsl:copy>
            <xsl:apply-templates select="$notes-added/node()"/>           
        </xsl:copy>     
    </xsl:template>

    <xsl:template match="seg[@type = 'foo'] | note" mode="add-notes">
        <xsl:next-match/>
        <footnote/>
    </xsl:template>

    <xsl:template match="note2" mode="add-notes">
        <xsl:next-match/>
        <appnote/>
    </xsl:template>

    <xsl:template match="footnote">
        <xsl:copy>
            <xsl:number level="any" format="1"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="appnote">
        <xsl:copy>
            <xsl:number level="any" format="a"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

http://xsltfiddle.liberty-development.net/948Fn5a/9