xslt:在for-each循环中只循环一次

时间:2016-05-24 07:06:28

标签: xml xslt

在应用xslt之前,我的XML看起来像这样:

<vehicle>
<driver repeatingtype="list">
 <data repeatingindex="1">
  <name>driver1</name>
  <age>25</age>
 </data>
 <data repeatingindex="2">
  <name>def</name>
  <age>25</age>
 </data>
 <data repeatingindex="3">
  <name>ghi</name>
  <age>25</age>
 </data>
</driver>
</vehicle>

我想写一个xslt,它以下列格式给我xml -

<vehicle>
<maindriver> [Comment: This always has the first element(1) in the driver list]
 <name>driver1</name>
 <age>25</age>
</maindriver>
<additionaldrivers>
 <name>def</name>
 <age>25</age>
 <name>ghi</name>
 <age>25</age>
</additionaldrives>
</vehicle>

如何编写xslt以获取页面列表中的第一个元素并将其放入主驱动程序标记中,并将其余元素放入附加驱动程序标记中。我正在寻找一些不重复模板代码的东西。我编写了以下xslt但驱动程序标记的代码重复 -

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

 

<xsl:template match="vehicle">
<maindriver>
<xsl:apply-templates select="driver/data[1]"/>
</maindriver>
<additionaldrivers>
<xsl:apply-templates select="driver"/>
</additionaldrivers>
</xsl:template>

<xsl:template match="driver/data[1]">
-----Code to capture the details----
</xsl:template>

<xsl:template match="driver">
<xsl:choose>
<xsl:when test="'$data -gt 1'">
 <xsl:for-each select="rowdata">
  ---- Repeating Code as of the main driver----
 </xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:template>

2 个答案:

答案 0 :(得分:1)

这个怎么样?

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="vehicle">
    <xsl:copy>
    <maindriver>
      <xsl:apply-templates select="driver/data[1]/*" mode="data"/>
    </maindriver>
    <additionaldrivers>
        <xsl:for-each select="driver/data">
          <xsl:if test="position()&gt;1">
            <xsl:apply-templates select="*" mode="data"/>
          </xsl:if>
        </xsl:for-each>
    </additionaldrivers>
    </xsl:copy>
  </xsl:template>    
  <xsl:template match="*" mode="data">
    <xsl:copy>
    <xsl:apply-templates select="*" mode="data"/>
    </xsl:copy>
  </xsl:template>    
</xsl:stylesheet>

在您的情况下,没有额外模式的解决方案也可以使用                                                                                                                                                             
                                        
    

如果你需要一个额外的司机元素,另一种方式...

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="vehicle">
    <xsl:copy>
    <maindriver>
      <xsl:apply-templates select="driver/data[1]/*"/>
    </maindriver>
    <additionaldrivers>
      <xsl:apply-templates select="driver/data" mode="additional"/>
    </additionaldrivers>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="data" mode="additional">
   <xsl:if test="position() &gt; 1">
    <driver>
      <xsl:apply-templates select="*"/>
    </driver>
   </xsl:if>
  </xsl:template>

  <xsl:template match="*">
   <xsl:copy>
    <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

首先,您应该更正文档中的所有语法错误:

输入中的标签不匹配:

<name>ghi</abc>

样式表声明:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

缺少vehicle模板的结束标记:

</xsl:template>

maindriver代码的结束标记不正确:

<maindriver>
<xsl:apply-templates select="driver/data[1]"/>
</maindriver>

然后,您可以在position() gt; 1中使用select作为其他驱动程序:

<xsl:apply-templates select="driver/data[ position() &gt; 1 ]"/>

所有在一起:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes" xmlns:xalan="http://xml.apache.org/xslt" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" />

<xsl:template match="/">
    <vehicle>
        <xsl:apply-templates select="vehicle"/>
    </vehicle>
</xsl:template>

<xsl:template match="vehicle">
    <maindriver>
        <xsl:apply-templates select="driver/data[1]"/>
    </maindriver>

    <additionaldrivers>
        <xsl:apply-templates select="driver/data[ position() &gt; 1 ]"/>
    </additionaldrivers>
</xsl:template>

<xsl:template match="driver/data">
    <xsl:copy-of select="*"/>
</xsl:template>

</xsl:stylesheet>