Xml 仅选择以下某些同级节点
我有以下XML:Xml 仅选择以下某些同级节点,xml,xslt,xpath,Xml,Xslt,Xpath,我有以下XML: <root> <table>Table 1</table> <foot>1.1</foot> <foot>2.2</foot> <p>...</p> <p>...</p> <table>Table X</table> <foot>M.1</foot> <foot>M.2</foot&
<root>
<table>Table 1</table>
<foot>1.1</foot>
<foot>2.2</foot>
<p>...</p>
<p>...</p>
<table>Table X</table>
<foot>M.1</foot>
<foot>M.2</foot>
<p>...</p>
<p>...</p>
<table>Table 132</table>
<foot>A.A.E</foot>
<foot>234</foot>
<p>...</p>
<p>...</p>
</root>
表1
1.1
2.2
表十
M.1
M.2
表132
A.A.E
234
我想将其转换为:
<root>
<table>
<text>Table 1</text>
<foot>1.1</foot>
<foot>2.2</foot>
</table>
<p>...</p>
<p>...</p>
<table>
<text>Table X</text>
<foot>M.1</foot>
<foot>M.2</foot>
</table>
<p>...</p>
<p>...</p>
<table>
<text>Table 132</text>
<foot>A.A.E</foot>
<foot>234</foot>
</table>
<p>...</p>
<p>...</p>
</root>
表1
1.1
2.2
表十
M.1
M.2
表132
A.A.E
234
我有以下XSL代码:
<xsl:template match="table">
<xsl:element name="table">
<xsl:element name="text">
<xsl:apply-templates />
</xsl:element>
<xsl:for-each select="following-sibling::foot">
<xsl:element name="foot">
<xsl:apply-templates />
</xsl:element>
</xsl:for-each>
</xsl:element>
其输出为:
<root>
<table>
<text>Table 1</text>
<foot>1.1</foot>
<foot>2.2</foot>
<foot>M.1</foot>
<foot>M.2</foot>
<foot>A.A.E</foot>
<foot>234</foot>
</table>
<p>...</p>
<p>...</p>
<table>
<text>Table X</text>
<foot>M.1</foot>
<foot>M.2</foot>
<foot>A.A.E</foot>
<foot>234</foot>
</table>
<p>...</p>
<p>...</p>
<table>
<text>Table 132</text>
<foot>A.A.E</foot>
<foot>234</foot>
</table>
<p>...</p>
<p>...</p>
</root>
表1
1.1
2.2
M.1
M.2
A.A.E
234
表十
M.1
M.2
A.A.E
234
表132
A.A.E
234
如果紧跟在
表
元素之后的n
个foot
元素,则如何仅选择紧跟在关闭表
元素之后的foot
元素。在此方面的任何帮助都将不胜感激 最干净的方法是使用XSL键。(此答案中的解决方案适用于所有XSLT版本。)
使用前一个
的唯一ID(请参阅)索引文档中的所有
元素
然后,
在相同唯一ID的帮助下选择属于每个
的
元素
这方面的功能等同于:
<xsl:template match="table">
<xsl:copy>
<text><xsl:apply-templates select="@*|node()"/></text>
<xsl:copy-of select="following-sibling::foot[
generate-id(preceding-sibling::table[1]) = generate-id(current())
]" />
</xsl:copy>
</xsl:template>
在此变体中,不需要XSL密钥。这两种情况的结果都是:
<root>
<table>
<text>Table 1</text>
<foot>1.1</foot>
<foot>2.2</foot>
</table>
<p>...</p>
<p>...</p>
<table>
<text>Table X</text>
<foot>M.1</foot>
<foot>M.2</foot>
</table>
<p>...</p>
<p>...</p>
<table>
<text>Table 132</text>
<foot>A.A.E</foot>
<foot>234</foot>
</table>
<p>...</p>
<p>...</p>
</root>
表1
1.1
2.2
表十
M.1
M.2
表132
A.A.E
234
注:
- 不要使用
。您只需编写
<代码>用于未预先确定元素名称的情况 - 避免
。在大多数情况下,与
和
一起工作更为优越
使用前一个
的唯一ID(请参阅)索引文档中的所有
元素
然后,
在相同唯一ID的帮助下选择属于每个
的
元素
这方面的功能等同于:
<xsl:template match="table">
<xsl:copy>
<text><xsl:apply-templates select="@*|node()"/></text>
<xsl:copy-of select="following-sibling::foot[
generate-id(preceding-sibling::table[1]) = generate-id(current())
]" />
</xsl:copy>
</xsl:template>
在此变体中,不需要XSL密钥。这两种情况的结果都是:
<root>
<table>
<text>Table 1</text>
<foot>1.1</foot>
<foot>2.2</foot>
</table>
<p>...</p>
<p>...</p>
<table>
<text>Table X</text>
<foot>M.1</foot>
<foot>M.2</foot>
</table>
<p>...</p>
<p>...</p>
<table>
<text>Table 132</text>
<foot>A.A.E</foot>
<foot>234</foot>
</table>
<p>...</p>
<p>...</p>
</root>
表1
1.1
2.2
表十
M.1
M.2
表132
A.A.E
234
注:
- 不要使用
。您只需编写
<代码>用于未预先确定元素名称的情况 - 避免
。在大多数情况下,与
和
一起工作更为优越
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="table">
<table>
<text>
<xsl:value-of select="."/>
</text>
<xsl:copy-of select="current-group()[self::foot]"/>
</table>
<xsl:copy-of select="current-group()[not(self::table or self::foot)]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
基本上,这是一个分组问题。如果您使用的是XSLT 2.0,则可以利用其内置的分组功能:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="table">
<table>
<text>
<xsl:value-of select="."/>
</text>
<xsl:copy-of select="current-group()[self::foot]"/>
</table>
<xsl:copy-of select="current-group()[not(self::table or self::foot)]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您能使用XSLT 2.0吗?对不起。XSLT2.0还可以。我应该指定它。你能使用XSLT2.0吗?对不起。XSLT2.0还可以。我应该指定它。对于XSLT 2.0环境,@michael.hor257k提供的解决方案当然更好。对于XSLT 2.0环境,@michael.hor257k提供的解决方案当然更好。