2014-01-29 66 views
1

我試圖通過XSLT從XML文件生成EPUB3導航文檔。通過XSLT從XML生成有效的EPUB3導航文檔

示例XML:

<div class="toc" id="s1"> 
    <p class="toc-title">Detailed Contents</p> 
    <ul class="toc"> 
     <li class="toc-item"> 
      <a class="ref-chap" id="a1" href="#a1">Preface</a> 
     </li> 
     <li class="book-section"> 
      <a class="ref-chap" id="a2" href="#a2"> 
       <b>Part I.</b> 
      </a> 
      <ul class="book-section"> 
       <li class="toc-item"> 
        <a class="ref-chap" id="a3" href="#a3"> 
         <b>Chapter 1</b> 
        </a> 
        <ul class="chapter-section"> 
         <li class="toc-item"> 
          <a class="ref-chap" id="a4" href="#a4"> 
           <b>Sub Chapter a</b> 
          </a> 
          <ul class="chapter-subsection"> 
           <li class="toc-item"> 
            <a class="ref-chap" id="a5" href="#a5">Sub Chapter B</a> 
           </li> 
          </ul> 
         </li> 
        </ul> 
       </li> 
      </ul> 
      <ul class="book-section"> 
       <li class="toc-item"> 
        <a class="ref-chap" id="a6" href="#a6"> 
         <b>Chapter 2</b> 
        </a> 
        <ul class="chapter-section"> 
         <li class="toc-item"> 
          <a class="ref-chap" id="a7" href="#a7"> 
           <b>Sub Chapter A</b> 
          </a> 
         </li> 
        </ul> 
       </li> 
      </ul> 
     </li> 
    </ul> 
</div> 

所需輸出:

<nav xmlns:epub="http://www.idpf.org/2007/ops" epub:type="toc" id="toc"> 
    <h1>Detailed Contents</h1> 
    <ol> 
     <li><a href="a1">Preface: To Our Readers</a></li> 
     <li><a href="a2"><b>Part I</b></a> 
      <ol> 
       <li><a href="a3"><b>Chapter 1</b></a> 
        <ol> 
         <li><a href="a4"><b>Sub Chapter A</b></a> 
          <ol> 
           <li><a href="a5">Sub Chapter B</a></li> 
          </ol> 
         </li> 
        </ol> 
       </li> 
       <li><a href="a6"><b>Chapter 2</b></a> 
        <ol> 
         <li><a href="a7"><b>Sub Chapter A</b></a></li> 
        </ol> 
       </li> 
      </ol> 
     </li> 
    </ol> 
</nav> 

我方面的問題是<ol>子部分我的,我需要它來關閉第2章後,但之後關閉第1章結束,而不是使用以下XSLT。

我的XSLT:

<?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:epub="http://www.idpf.org/2007/ops" 
    exclude-result-prefixes="xs epub" 
    version="2.0"> 

    <xsl:output method="xhtml" include-content-type="no" xpath-default-namespace="http://www.w3.org/1999/xhtml" indent="yes"/> 

    <xsl:strip-space elements="*"/> 

    <xsl:template match="div[@class='toc']"> 
     <xsl:element name="nav"> 
      <xsl:attribute name="epub:type" select="'toc'"/> 
      <xsl:attribute name="id" select="'toc'"/> 
      <xsl:element name="h1"> 
       <xsl:value-of select="//div[@class='toc']/p[@class='toc-title']"/> 
      </xsl:element> 
      <xsl:apply-templates/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="div[@class='toc']//ul[@class='toc'] | div[@class='toc']//ul[@class='book-section'] | div[@class='toc']//ul[@class='chapter-section' or @class='chapter-subsection']"> 
     <xsl:element name="ol"> 
      <xsl:apply-templates/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="div[@class='toc']//li[@class='toc-item']"> 
     <xsl:element name="li"> 
      <xsl:apply-templates/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="div[@class='toc']//li[@class='book-section']"> 
     <xsl:element name="li"> 
      <xsl:apply-templates xml:space="default"/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="a[@class='ref-chap']"> 
     <xsl:element name="a"> 
      <xsl:attribute name="href" select="concat(substring-after(@href, '#'),'.xhtml')"/> 
      <xsl:apply-templates/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template priority="1" match="ul[@class='chapter-section' or @class='chapter-subsection']//a[@class='ref-chap']"> 
     <xsl:variable name="pagenumber" select="following-sibling::a[@class='page-ref']"/> 
     <xsl:element name="a"> 
      <xsl:attribute name="href" select="concat(substring-after(ancestor::ul[@class='chapter-section'][1]/preceding-sibling::a[@class='ref-chap'][1]/@href, '#'),'.xhtml','#page',$pagenumber)"/> 
      <xsl:apply-templates/> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

給了我一個nonvalid EPUB3導航DOC:

<nav xmlns:epub="http://www.idpf.org/2007/ops" epub:type="toc" id="toc"> 
    <h1>Detailed Contents</h1>Detailed Contents 
    <ol> 
     <li> 
     <a href="a1.xhtml">Preface</a> 
     </li> 
     <li> 
     <a href="a2.xhtml">Part I.</a> 
     <ol> 
      <li> 
       <a href="a3.xhtml">Chapter 1</a> 
       <ol> 
        <li> 
        <a href="a3.xhtml#page">Sub Chapter a</a> 
        <ol> 
         <li> 
          <a href="a3.xhtml#page">Sub Chapter B</a> 
         </li> 
        </ol> 
        </li> 
       </ol> 
      </li> 
     **</ol> 
     <ol>** 
      <li> 
       <a href="a6.xhtml">Chapter 2</a> 
       <ol> 
        <li> 
        <a href="a6.xhtml#page">Sub Chapter A</a> 
        </li> 
       </ol> 
      </li> 
     </ol> 
     </li> 
    </ol> 
</nav> 

重點加入**來表示這些標籤是哪裏出了問題。他們不應該在輸出中。

回答

3

你想要做的是將ul [@ class ='book-section']

有不同的方法來做到這一點,一個是在李[@類=「書節」]的父模板使用,每個組,所以你能說的模板更改爲:

<xsl:template match="div[@class='toc']//li[@class='book-section']"> 
    <xsl:element name="li"> 
     <xsl:apply-templates select="xhtml:a[@class='ref-chap']"/> 
     <xsl:for-each-group select="ul[@class='book-section']" group-by="@class"> 
      <ol> 
       <xsl:apply-templates select="current-group()/node()"/> 
      </ol> 
     </xsl:for-each-group> 
    </xsl:element> 
</xsl:template> 

另一種方法是隻匹配第一個上行的[@類=「書節」]但隨後將此於以下的孩子,太像這樣:

<xsl:template match="div[@class='toc']//ul[@class='book-section'][1]"> 
    <xsl:element name="ol"> 
     <xsl:apply-templates select="* | following-sibling::ul[@class='book-section']/*"/> 
    </xsl:element> 
</xsl:template> 
+0

真棒。第一個建議很好。我必須在之後添加以便錨點,文本和輸出。 – user2093335