我有目录的XML。我正在从列表中为XML中的每个锚点生成命名的.xhtml页面。
TOC的结构包含章节,其中还列出了这些章节中的子章节。我试图使用前一章锚的@href值动态命名这些子锚点。
示例XML:
<div class="toc" id="s9781483331812.i34"><a class="page" id="pbr-v" title="v"/>
<p class="toc-title">Contents</p>
<ul class="toc">
<li class="toc-item">
<a class="ref-chap" href="#s132" id="s35"><b>Preface</b></a>
<a class="page-ref" href="#pbr-vii" id="s36"><b>vii</b></a>
</li>
<li class="toc-item">
<a class="ref-chap" href="#s135" id="s37"><b>Introduction</b></a>
<a class="page-ref" href="#pbr-xi" id="s38"><b>xi</b></a>
</li>
<li class="toc-item">
<span class="toc-label" title="1"><b>1.</b></span>
<a class="ref-chap" href="#s147" id="s39"><b>Chapter</b></a>
<a class="page-ref" href="#pbr-1" id="s40"><b>1</b></a>
<ul class="chapter-section">
<li class="toc-item">
<a class="ref-chap" href="#s152" id="s41">Subsection 1</a>
<a class="page-ref" href="#pbr-2" id="s42">2</a>
</li>
<li class="toc-item">
<a class="ref-chap" href="#s158" id="s43">Subsection 2</a>
<a class="page-ref" href="#pbr-6" id="s44">6</a>
</li>
<li class="toc-item">
<a class="ref-chap" href="#s159" id="s45">Subsection 3</a>
<a class="page-ref" href="#pbr-10" id="s46">10</a>
</li>
</ul>
</li>
</ul>
示例XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</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="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']//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='toc']//li[@class='toc-item']//a[@class='ref-chap'][last()]/@href, '#'),'.xhtml','#page',$pagenumber)"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
我想要的输出是:
<div class="toc" id="s9781483331812.i34">
<a class="page" id="pbr-v" title="v"/>
<p class="toc-title">Contents</p>
<ul class="toc">
<li>
<a href="s132.xhtml"><b>Preface</b></a>
<a class="page-ref" href="#pbr-vii" id="s36"><b>vii</b></a>
</li>
<li>
<a href="s135.xhtml"><b>Introduction</b></a>
<a class="page-ref" href="#pbr-xi" id="s38"><b>xi</b></a>
</li>
<li>
<span class="toc-label" title="1"><b>1.</b></span>
<a href="s147.xhtml"><b>Chapter</b></a>
<a class="page-ref" href="#pbr-1" id="s40"><b>1</b></a>
<ul class="chapter-section">
<li>
<a href="s147.xhtml#page2">Subsection 1</a>
<a class="page-ref" href="#pbr-2" id="s42">2</a>
</li>
<li>
<a href="s147.xhtml#page6">Subsection 2</a>
<a class="page-ref" href="#pbr-6" id="s44">6</a>
</li>
<li>
<a href="s147.xhtml#page10">Subsection 3</a>
<a class="page-ref" href="#pbr-10" id="s46">10</a>
</li>
</ul>
</li>
</ul>
我收到错误“不允许多个项目的序列作为substring-after()的第一个参数(”#s132“,”#s135“,...)”。显然我的XPath正在选择多个值而不是一个。但是,我无法弄清楚如何解决这个问题。
注意:章节小节的数量是未知的,可能会有所不同。
答案 0 :(得分:1)
您的XPath表达式
ancestor::ul[@class='toc']//li[@class='toc-item']//a[@class='ref-chap'][last()]/@href
肯定会捡到太多 - 它会查看toc中所有ref-chap
列表项内的所有toc-item
个锚点,并给出一个由最后一个锚点组成的序列ref-chap
在他们各自的父母里面。由于没有toc-item
包含多个ref-chap
,这意味着所有。
鉴于您目前处于特定ref-chap
的上下文中,您无需一直走到toc
级别,您只需要向上移动到最近的chapter-section
级别ref-chap
ul元素,然后拉出该元素最近的前一个兄弟ancestor::ul[@class='chapter-section'][1]/preceding-sibling::a[@class='ref-chap'][1]/@href
:
ancestor::
请注意,由于preceding-sibling::
和[1]
是反向轴,因此“最近”匹配项(即文档顺序中的最后一项)为{{1}}。