在这里,我想选择第一个<w:p>
usingfor-each
语句的下一个兄弟,直到它遇到下一个<w:p>
具有<w:pPr><w:pStyle w:val="Heading1"/></w:pPr>
.
此 XSLT 2.0 转换显示了使用 XPAth 2.0 运算符的一种方法 >>
:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
exclude-result-prefixes="w xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="*/w:p[1]">
<xsl:variable name="vNextWP" select=
"following-sibling::w:p
[w:pPr/w:pStyle/@w:val='Heading1']
[1]
"/>
<xsl:copy-of select=
"following-sibling::w:p[$vNextWP >> .]"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p> <!-- Current Node -->
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>
Paragraph1
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>
Paragraph2
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>
Paragraph3
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>
Paragraph4
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>
Paragraph5
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>
Paragraph6
</w:t>
</w:r>
</w:p>
</w:body>
</w:document>
正是想要的节点被选中并复制到输出:
<w:p xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:pPr>
</w:pPr>
<w:r>
<w:t>
Paragraph2
</w:t>
</w:r>
</w:p>
<w:p xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:pPr>
</w:pPr>
<w:r>
<w:t>
Paragraph3
</w:t>
</w:r>
</w:p>
更新:OP已经澄清了转换的结果是什么(分组),所以这里是:
一、XSLT 1.0 解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
exclude-result-prefixes="w">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kFollowing"
match="w:p[not(w:pPr/w:pStyle/@w:val = 'Heading1')]
|
w:tbl"
use="generate-id(preceding-sibling::w:p
[w:pPr/w:pStyle/@w:val = 'Heading1'][1])
"/>
<xsl:template match="/*">
<Document>
<xsl:apply-templates/>
</Document>
</xsl:template>
<xsl:template match=
"w:p[w:pPr/w:pStyle/@w:val = 'Heading1']">
<Heading1>
<xsl:apply-templates mode="inGroup" select=
". | key('kFollowing', generate-id())"/>
</Heading1>
</xsl:template>
<xsl:template match="*" mode="inGroup">
<paragraph>
<xsl:value-of select="normalize-space(.//w:t)"/>
</paragraph>
</xsl:template>
<xsl:template match="w:body/*" priority="-1"/>
</xsl:stylesheet>
当此转换应用于新提供的 XML 文档时:
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p> <!-- Current Node -->
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>
Paragraph1
</w:t>
</w:r>
</w:p>
<w:tbl>
<w:t>table info
</w:t>
</w:tbl>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>
Paragraph2
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>
Paragraph3
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>
Paragraph4
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>
Paragraph5
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>
Paragraph6
</w:t>
</w:r>
</w:p>
</w:body>
</w:document>
产生了想要的正确结果:
<Document>
<Heading1>
<paragraph>Paragraph1</paragraph>
<paragraph>table info</paragraph>
<paragraph>Paragraph2</paragraph>
<paragraph>Paragraph3</paragraph>
</Heading1>
<Heading1>
<paragraph>Paragraph4</paragraph>
<paragraph>Paragraph5</paragraph>
</Heading1>
<Heading1>
<paragraph>Paragraph6</paragraph>
</Heading1>
</Document>
二、XSLT 2.0 解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
exclude-result-prefixes="w" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<Document>
<xsl:for-each-group
select="*/*"
group-starting-with="w:p[w:pPr/w:pStyle/@w:val = 'Heading1']">
<Heading1>
<xsl:for-each select="current-group()//w:t">
<paragraph>
<xsl:sequence select="normalize-space(.)"/>
</paragraph>
</xsl:for-each>
</Heading1>
</xsl:for-each-group>
</Document>
</xsl:template>
</xsl:stylesheet>
当这个 XSLT 2.0 转换应用于同一个 XML 文档(上图)时,会产生同样想要的正确结果:
<Document>
<Heading1>
<paragraph>Paragraph1</paragraph>
<paragraph>table info</paragraph>
<paragraph>Paragraph2</paragraph>
<paragraph>Paragraph3</paragraph>
</Heading1>
<Heading1>
<paragraph>Paragraph4</paragraph>
<paragraph>Paragraph5</paragraph>
</Heading1>
<Heading1>
<paragraph>Paragraph6</paragraph>
</Heading1>
</Document>