如何使用XSLT在pageTarget中添加playOrder Sequence?

时间:2018-04-30 11:03:50

标签: xslt

每个pageTarget和navPoint都需要playOrder属性。它提供了一种方法来将所有pageTargets和navPoints整理成一个有序的序列,该序列反映了它们在书脊的正常播放顺序中的顺序,如脊椎文件中所示。 playOrder必须增加1并继续使用navPoint。

输入:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
    <head>
        <meta name="dtb:uid" content="urn:uuid:29d919dd-24f5-4384-be78-b447c9dc299b"/>
    </head>
    <docTitle>
        <text></text>
    </docTitle>
    <navMap>
        <navPoint id="navpoint1" playOrder="1">
            <navLabel>
                <text>Chapter 1</text>
            </navLabel>
            <content src="ch1.xhtml"/>
        </navPoint>
        <navPoint id="navpoint2" playOrder="2">
            <navLabel>
                <text>Chapter 2</text>
            </navLabel>
            <content src="ch2.xhtml"/>
        </navPoint>
</navMap>

    <pageList id="page-mapping" class="page-mapping">
        <navLabel><text>Page Mapping</text></navLabel>
        <pageTarget id="page1" value="1" type="normal"><navLabel><text>1</text></navLabel><content src="ch1.xhtml#pg1" /></pageTarget>
        <pageTarget id="page2" value="2" type="normal"><navLabel><text>2</text></navLabel><content src="ch2.xhtml#pg2" /></pageTarget>
    </pageList>
</ncx>

期待输出:

        <navPoint id="navpoint2" playOrder="2">
            <navLabel>
                <text>Chapter 2</text>
            </navLabel>
            <content src="ch2.xhtml"/>
        </navPoint>
</navMap>

    <pageList id="page-mapping" class="page-mapping">
        <navLabel><text>Page Mapping</text></navLabel>
        <pageTarget id="page1" value="1" type="normal" playOrder="3"><navLabel><text>1</text></navLabel><content src="ch1.xhtml#pg1" /></pageTarget>
        <pageTarget id="page2" value="2" type="normal" playOrder="4"><navLabel><text>2</text></navLabel><content src="ch2.xhtml#pg2" /></pageTarget>
    </pageList>
</ncx>

在这种情况下如何在XSLT上编码..请告知我。 谢谢

2 个答案:

答案 0 :(得分:2)

因为您的源XML具有默认命名空间(http://www.daisy.org/z3986/2005/ncx/),我们将在样式表中将其声明为:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ncx="http://www.daisy.org/z3986/2005/ncx/"
    version="1.0">

然后我们计算navPoint个节点的数量并将它们存储在变量

<xsl:variable name="navPointCount" select="count(//ncx:navPoint)"/>

我们还有一个身份模板来复制所有节点

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

然后我们匹配目标节点pageTarget,现在变为ncx:pageTarget以告诉它是ncx名称空间中的pageTarget节点

<xsl:template match="ncx:pageTarget">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <!-- here, playOrder attribute is being inserted -->
        <xsl:attribute name="playOrder">
            <xsl:value-of select="count(preceding-sibling::ncx:pageTarget) + $navPointCount + 1"/>
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

整个样式表现在变为:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ncx="http://www.daisy.org/z3986/2005/ncx/"
    version="1.0">

    <xsl:variable name="navPointCount" select="count(//ncx:navPoint)"/>

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

    <xsl:template match="ncx:pageTarget">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="playOrder">
                <xsl:value-of select="count(preceding-sibling::ncx:pageTarget) + $navPointCount + 1"/>
            </xsl:attribute>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

在行动here中查看。

答案 1 :(得分:2)

您可以使用<xsl:number count="navPoint | pageTarget" level="any"/>确定数字,然后为该元素创建属性:

  <xsl:template match="pageTarget">
      <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:attribute name="playOrder">
              <xsl:number count="navPoint | pageTarget" level="any"/>
          </xsl:attribute>
          <xsl:apply-templates/>
      </xsl:copy>
  </xsl:template>

其余部分可以通过身份转换来处理,请参阅XSLT 3中的在线示例

https://xsltfiddle.liberty-development.net/6qVRKvV/1

哪个

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xpath-default-namespace="http://www.daisy.org/z3986/2005/ncx/"
    version="3.0">

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

  <xsl:template match="pageTarget">
      <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:attribute name="playOrder">
              <xsl:number count="navPoint | pageTarget" level="any"/>
          </xsl:attribute>
          <xsl:apply-templates/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>