考虑到这样的事情:
<source>
<somestuff>
<thead>
<row>C1</row>
</thead>
<tbody>
<row>C2</row>
<row>C3</row>
</tbody>
</somestuff>
<somestuff>
<tbody>
<row>C4</row>
<row>C5</row>
</tbody>
</somestuff>
<somestuff>
<tbody>
<row>C6</row>
<row>C7</row>
</tbody>
</somestuff>
</source>
我需要将thead元素的内容作为第一个子元素复制到以下tbody元素。 (可能有任意数量的元素。)导致:
<source>
<somestuff>
<tbody>
<row>C1</row>
<row>C2</row>
<row>C3</row>
</tbody>
</somestuff>
<somestuff>
<tbody>
<row>C4</row>
<row>C5</row>
</tbody>
</somestuff>
<somestuff>
<tbody>
<row>C6</row>
<row>C7</row>
</tbody>
</somestuff>
</source>
我试过这个
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity" >
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tbody/*[1]">
<xsl:copy-of select=
"preceding-sibling::*[1]
[name()='thead']/row"/>
<xsl:call-template name="identity"/>
</xsl:template>
<!-- deleting the Head node -->
<xsl:template match="//thead"/>
</xsl:stylesheet>
但失败了。谢谢。拉尔夫
答案 0 :(得分:1)
试试这个:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity" >
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tbody/*[1]">
<xsl:apply-templates select="../preceding-sibling::thead[1]/node()" />
<xsl:call-template name="identity" />
</xsl:template>
<!-- deleting the Head node -->
<xsl:template match="thead"/>
</xsl:stylesheet>
原始样式表的关键问题是您正在尝试选择
preceding-sibling::*[1][name()='thead']
当上下文节点是tbody
的子时,而不是tbody
本身。在查找..
之前,我的版本会添加tbody
以启动preceding-sibling::thead[1]
。
请注意,这不包括空tbody
或thead
没有tbody
的情况。要抓住这些案例,最好不要模仿thead
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity" >
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- ignore a tbody that immediately follows a thead -->
<xsl:template match="tbody[preceding-sibling::*[1]/self::thead]"/>
<xsl:template match="thead">
<tbody>
<xsl:apply-templates select="@*|node()" />
<xsl:apply-templates select="following-sibling::*[1]/self::tbody/node()" />
</tbody>
</xsl:template>
</xsl:stylesheet>
这会在原始XML上产生相同的结果,但也可以处理
之类的内容 <somestuff>
<thead>
<row>C9</row>
</thead>
</somestuff>
或
<somestuff>
<thead>
<row>C9</row>
</thead>
<tbody>
</tbody>
</somestuff>