只需使用这个 XPath 1.0 表达式:
/*/*/w:p[not(substring-after(@pStyle,'Heading')
>=
substring-after(preceding-sibling::*[1]/@pStyle,'Heading')
)
]
选择同一组元素的相应 XPath 2.0 表达式是:
/*/*/w:p[1]
|
/*/*/w:p[position() ge 2]
[xs:integer(substring-after(@pStyle,'Heading'))
lt
xs:integer(substring-after(preceding-sibling::*[1]/@pStyle,'Heading'))
]
如果您使用 XSLT 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="Undefined!!!">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"w:p[xs:integer(substring-after(@pStyle,'Heading'))
ge
xs:integer(substring-after(preceding-sibling::*[1]/@pStyle,'Heading'))
]"/>
</xsl:stylesheet>
当应用于提供的 XML 文档时(固定为格式正确):
<w:document xmlns:w="Undefined!!!">
<w:body>
<w:p pStyle="Heading1">Para1</w:p>
<w:p pStyle="Heading2">Para2</w:p>
<w:p pStyle="Heading3">Para3</w:p>
<w:p pStyle="Heading4">Para4</w:p>
<w:p pStyle="Heading1">Para5</w:p>
<w:p pStyle="Heading3">Para6</w:p>
<w:p pStyle="Heading4">Para7</w:p>
<w:p pStyle="Heading2">Para8</w:p>
<w:p pStyle="Heading3">Para9</w:p>
<w:p pStyle="Heading1">Para10</w:p>
</w:body>
</w:document>
产生了想要的正确结果:
<w:document xmlns:w="Undefined!!!">
<w:body>
<w:p pStyle="Heading1">Para1</w:p>
<w:p pStyle="Heading1">Para5</w:p>
<w:p pStyle="Heading2">Para8</w:p>
<w:p pStyle="Heading1">Para10</w:p>
</w:body>
</w:document>
由于 XPath 1.0 缺乏强类型,因此覆盖标识规则的相应 XSLT 1.0 解决方案稍微简单一些:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="Undefined!!!">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"w:p[substring-after(@pStyle,'Heading')
>=
substring-after(preceding-sibling::*[1]/@pStyle,'Heading')
]"/>
</xsl:stylesheet>
或者,您可以简单地使用此解决方案开头的表达式:
XSLT 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="Undefined!!!" exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<w:document xmlns:w="Undefined!!!">
<w:body>
<xsl:copy-of select=
"/*/*/w:p[1]
|
/*/*/w:p[position() ge 2]
[xs:integer(substring-after(@pStyle,'Heading'))
lt
xs:integer(substring-after(preceding-sibling::*[1]/@pStyle,'Heading'))
]
"/>
</w:body>
</w:document>
</xsl:template>
</xsl:stylesheet>
XSLT 1.0:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="Undefined!!!">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<w:document xmlns:w="Undefined!!!">
<w:body>
<xsl:copy-of select=
"/*/*/w:p
[not(substring-after(@pStyle,'Heading')
>=
substring-after(preceding-sibling::*[1]/@pStyle,'Heading')
)
]
"/>
</w:body>
</w:document>
</xsl:template>
</xsl:stylesheet>
所有上述三个 XSLT 转换都会产生所需的正确结果。