我在XSLT中提出了一个小问题。我需要XPath来验证一个条件。以下是我的XML。
<root>
<para>
Erlanger and several associates formed a syndicate to acquire the lease of an island in the West Indies for £55,000. The idea was to mine the <page num="44"/>island for phosphates.
</para>
<para>
<content-style font-style="bold">2.25</content-style> A commission or payment that a promoter receives upon transfer of property to a company must also be disclosed.
<para>
board were all nominees of Green and Smith; <page num="45"/>accordingly, disclosure </para>
</para>
<para>
<content-style font-style="bold">2.26</content-style> If a promoter contracts with the company whether as vendor<footnote num="57" id="fn57">
<para>
<case>
<casename>
<content-style font-style="italic">Re Leeds & Hanley Theatres of Varieties Ltd</content-style>
</casename> [1902] Ch 809 (Court of Appeal, England)
</case>.
</para>
</footnote> or purchaser,<footnote num="58" id="fn58">
<para>
<case>
<casename>
<content-style font-style="italic">Habib Abdul Rahman v Abdul Cader</content-style>
</casename> (1886) 4 Ky 193 (High Court of the Straits Settlements)
</case>.
</para>
</footnote> the fact that he is a contractor must be disclosed.
</para>
</root>
和XSL如下。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:ntw="Number2Word.uri"
exclude-result-prefixes="ntw">
<xsl:output method="html"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="ThisDocument" select="document('')"/>
<xsl:template match="/">
<xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE html>]]></xsl:text>
<html>
<head>
<xsl:text disable-output-escaping="yes"><![CDATA[</meta>]]></xsl:text>
<title>
<xsl:value-of select="chapter/title[1]/*"/>
</title>
<link rel="stylesheet" href="C:\Users\u0138039\Desktop\Proview\SG\Commentary_SG_XML-03032014\SG-Business Guide to Competition Law\05192014\XSLT\main.css" type="text/css"/>
<xsl:text disable-output-escaping="yes"><![CDATA[</link>]]></xsl:text>
</head>
<body>
<xsl:apply-templates/>
<xsl:if test="//footnote">
<section class="tr_footnotes">
<hr/>
<xsl:apply-templates select="//page[not(ancestor::toc)]| //footnote" mode="footnote"/>
</section>
</xsl:if>
</body>
</html>
</xsl:template>
<xsl:template match="footnote">
<xsl:variable name="varHeaderNote" select='concat("f",@num)'/>
<xsl:variable name="varFootNote" select='concat("#ftn.",@num)'/>
<sup>
<a name="{$varHeaderNote}" href="{$varFootNote}" class="tr_ftn">
<xsl:value-of select="@num"/>
</a>
</sup>
</xsl:template>
<xsl:template match="page" mode="footnote">
<xsl:processing-instruction name="pb">
<xsl:text>label='</xsl:text>
<xsl:value-of select="./@num"/>
<xsl:text>'</xsl:text>
<xsl:text>?</xsl:text>
</xsl:processing-instruction>
</xsl:template>
<xsl:template match="footnote" mode="footnote">
<div class="tr_footnote">
<div class="footnote">
<sup>
<a>
<xsl:attribute name="name">
<xsl:text>ftn.</xsl:text>
<xsl:value-of select="@num"/>
</xsl:attribute>
<xsl:attribute name="href">
<xsl:text>#f</xsl:text>
<xsl:value-of select="@num"/>
</xsl:attribute>
<xsl:attribute name="class">
<xsl:text>tr_ftn</xsl:text>
</xsl:attribute>
<xsl:value-of select="@num"/>
</a>
</sup>
<xsl:apply-templates/>
</div>
</div>
</xsl:template>
</xsl:stylesheet>
在这里,当我运行这个时,我得到<?pb label='44'?><?pb label='45'?>
我需要的条件如下。
there should only be a `footnote` following `page` and there should be no `page` between `page` and `footnote`
简单来说,通过上面的例子,有两个page
,忽略所有其他标记,只考虑page
,结构如下所示。
page num='44'
page num='45'
footnote
此处我只想抓取page num='45'
并离开page num='44'
,因为page num='44'
后面是另一个page
但不是直接footnote
,这非常令人困惑,请让我知道我该怎么做。
可以找到演示here
由于
答案 0 :(得分:2)
要仅捕获包含至少一个脚注的页面,您可以使用类似
的测试(following::page | following::footnote)[1][self::footnote]
即。按文档顺序获取以下所有page
和footnote
元素,并检查这些元素中的第一个元素是否为footnote
- 如果它不是那么“{1}}。干预page
或者根本没有page
或footnote
元素,无论我们知道此页面上没有脚注。
<xsl:template match="page[(following::page | following::footnote)[1][self::footnote]]" mode="footnote">
<xsl:processing-instruction name="pb">
<xsl:text>label='</xsl:text>
<xsl:value-of select="./@num"/>
<xsl:text>'</xsl:text>
<xsl:text>?</xsl:text>
</xsl:processing-instruction>
</xsl:template>
<xsl:template match="page" mode="footnote" />
答案 1 :(得分:2)
简单来说,通过上面的例子,有两个
page
,by 忽略所有其他标记并仅考虑page
结构 看起来如下。page num='44' page num='45' footnote
此处我只想抓取
page num='45'
并离开page num='44'
,因为page num='44'
后面跟着另一个page
但不是 直接footnote
要选择紧跟脚注的页面,请使用:
page[following-sibling::*[1][self::footnote]]
如果脚注始终以页面开头,您还可以使用:
footnote/preceding-sibling::page[1]
在您的真实示例中,页面和脚注是不是兄弟姐妹,您应该使用Ian的答案,即:
page[(following::page | following::footnote)[1][self::footnote]]
或(假设只有脚注块):
footnote[1]/preceding::page[1]
答案 2 :(得分:1)
当您匹配page
时,您可以检查 next 脚注是否有前一页当前页面。如果不是,那么你不会打印出它的处理指令,因为它是一个没有脚注的页面。
<xsl:template match="page" mode="footnote">
<xsl:if test="following::footnote[1][preceding::page[1]/@num = current()/@num]">
<xsl:processing-instruction name="pb">
<xsl:text>label='</xsl:text>
<xsl:value-of select="./@num"/>
<xsl:text>'</xsl:text>
<xsl:text>?</xsl:text>
</xsl:processing-instruction>
</xsl:if>
</xsl:template>