如何复制具有名字的前一个兄弟?

时间:2013-02-12 16:10:24

标签: xslt

考虑到这样的事情:

<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>

但失败了。谢谢。拉尔夫

1 个答案:

答案 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]

请注意,这不包括空tbodythead没有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>