我必须为两个节点之间的所有特定节点选择和应用模板,但是在特定节点处停止..... 例如,在此代码中:
.........
<p class="capo">1</p>
<p class="busta">prima</p>
<p class="dialogo1">dati</p>
<p class="dialogo2">dati</p>
<p class="dialogo3">dati</p>
<p class="busta">seconda:</p>
<p class="dialogo4">dati</p>
<p class="dialogo5">dati</p>
<p class="capo">2</p>
<p class="capo">3</p>
<p class="dialogo6">dati</p>
<p class="capo">4</p>
<p class="busta">terza:</p>
..........
我需要在标记<p class="dialogo"/>
之间和之后选择所有<p class="busta"/>
,但如果我找到了<p class="capo"/>
,我需要停止...
结果必须是这样的:
<busta>
<p class="dialogo1">dati</p>
<p class="dialogo2">dati</p>
<p class="dialogo3">dati</p>
</busta>
<busta>
<p class="dialogo4">dati</p>
<p class="dialogo5">dati</p>
</busta>
..........
在"template match="p[@class='busta']"
我正在使用以下代码,但选择不要在找到变调夹并停止对话6 "select="following-sibling::p[@class='busta'] [generate-id(preceding-sibling::p[@class='busta'][1]) = generate-id(current())]"/>"
提前致谢
答案 0 :(得分:1)
假设XSLT 2或3这是for-each-group group-starting-with="p[@class = 'busta']"
分别使用group-ending-with="p[@class = 'capo']"
的教科书:
<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:output method="xml" indent="yes" />
<xsl:template match="body">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="p[@class = 'busta']">
<xsl:if test="self::p[@class = 'busta']">
<busta>
<xsl:for-each-group select="current-group()[position() gt 1]" group-ending-with="p[@class = 'capo']">
<xsl:if test="position() eq 1">
<xsl:apply-templates select="current-group()[not(self::p[@class = 'capo'])]"/>
</xsl:if>
</xsl:for-each-group>
</busta>
</xsl:if>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
改变
<body>
<p class="capo">1</p>
<p class="busta">prima</p>
<p class="dialogo1">dati</p>
<p class="dialogo2">dati</p>
<p class="dialogo3">dati</p>
<p class="busta">seconda:</p>
<p class="dialogo4">dati</p>
<p class="dialogo5">dati</p>
<p class="capo">2</p>
<p class="capo">3</p>
<p class="dialogo6">dati</p>
<p class="capo">4</p>
<p class="busta">terza:</p>
</body>
进入
<body>
<busta>
<p class="dialogo1">dati</p>
<p class="dialogo2">dati</p>
<p class="dialogo3">dati</p>
</busta>
<busta>
<p class="dialogo4">dati</p>
<p class="dialogo5">dati</p>
</busta>
<busta/>
</body>
请参阅https://xsltfiddle.liberty-development.net/6qM2e2h。
对于XSLT 2,您需要将xsl:mode
拼出为身份转换模板
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
为了举例说明p
元素不是输入元素的子元素,而是作为元素节点序列作为参数传入,下面是这样的(https://xsltfiddle.liberty-development.net/6qM2e2h/1):
<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:output method="xml" indent="yes" />
<xsl:param name="paragraphs" as="element()*">
<p class="capo">1</p>
<p class="busta">prima</p>
<p class="dialogo1">dati</p>
<p class="dialogo2">dati</p>
<p class="dialogo3">dati</p>
<p class="busta">seconda:</p>
<p class="dialogo4">dati</p>
<p class="dialogo5">dati</p>
<p class="capo">2</p>
<p class="capo">3</p>
<p class="dialogo6">dati</p>
<p class="capo">4</p>
<p class="busta">terza:</p>
</xsl:param>
<xsl:template match="/">
<xsl:for-each-group select="$paragraphs" group-starting-with="p[@class = 'busta']">
<xsl:if test="self::p[@class = 'busta']">
<busta>
<xsl:for-each-group select="current-group()[position() gt 1]" group-ending-with="p[@class = 'capo']">
<xsl:if test="position() eq 1">
<xsl:apply-templates select="current-group()[not(self::p[@class = 'capo'])]"/>
</xsl:if>
</xsl:for-each-group>
</busta>
</xsl:if>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
那么for-each-group
取决于您使用的输入选择的位置和方式以及取决于模板匹配。您可以编写一个模板或函数,将p
元素的序列作为输入参数,并将for-each-group
放入模板或函数体中。