在XSLT中使用for循环

时间:2014-04-16 14:50:20

标签: xml xslt

我有以下格式的xml:

<?xml version="1.0" encoding="UTF-8"?>
<response>
   <cases>
      <case>CASE-ONE</case>
      <case>CASE-TWO</case>
   </cases>
   <results>
      <Final-Results>
         <issues>
            <row>
               <IKEY>2014-03-26-05.22.22.193840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </Final-Results>
      <Final-Results>
         <issues>
            <row>
               <IKEY>2014-03-26-05.05.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
            <row>
               <IKEY>2014-03-26-05.10.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </Final-Results>
   </results>
</response>

现在,我想使用XSLT将上述xml转换为以下格式:

<?xml version="1.0" encoding="UTF-8"?>
<response>
   <cases>
      <case>
         CASE-ONE
         <issues>
            <row>
               <IKEY>2014-03-26-05.22.22.193840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </case>
      <case>
         CASE-TWO
         <issues>
            <row>
               <IKEY>2014-03-26-05.05.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
            <row>
               <IKEY>2014-03-26-05.10.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </case>
   </cases>
</response>

我们的想法是将内容在第一个<issues> </issues>标记之间移动到第一个<case> </case>标记,将第二个<issues> </issues>标记移动到第二个标记,依此类推。此处<case>代码和<issues>代码的数量不确定。所以,我认为我必须在这里使用循环类的东西。老实说,我不是使用XSLT的专家。如果您能提供解决方案,那就太好了。如果我的问题不清楚,请随时添加评论,以便我可以用更好的词语。 提前谢谢。

3 个答案:

答案 0 :(得分:3)

无需使用for循环。请改用identity transformxsl:apply-templates

XML输入

<response>
    <cases>
        <case>CASE-ONE</case>
        <case>CASE-TWO</case>
    </cases>
    <results>
        <Final-Results>
            <issues>
                <row>
                    <IKEY>2014-03-26-05.22.22.193840T01</IKEY>
                    <PRTY>999</PRTY>
                </row>
            </issues>
        </Final-Results>
        <Final-Results>
            <issues>
                <row>
                    <IKEY>2014-03-26-05.05.51.077840T01</IKEY>
                    <PRTY>999</PRTY>
                </row>
                <row>
                    <IKEY>2014-03-26-05.10.51.077840T01</IKEY>
                    <PRTY>999</PRTY>
                </row>
            </issues>
        </Final-Results>
    </results>
</response>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates select="@*|cases"/>
        </xsl:copy>        
    </xsl:template>

    <xsl:template match="case">
        <xsl:variable name="pos" select="position()"/>
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:apply-templates select="/*/results/Final-Results[position()=$pos]/issues"/>
        </xsl:copy>        
    </xsl:template>

</xsl:stylesheet>

XML输出

<response>
   <cases>
      <case>CASE-ONE<issues>
            <row>
               <IKEY>2014-03-26-05.22.22.193840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </case>
      <case>CASE-TWO<issues>
            <row>
               <IKEY>2014-03-26-05.05.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
            <row>
               <IKEY>2014-03-26-05.10.51.077840T01</IKEY>
               <PRTY>999</PRTY>
            </row>
         </issues>
      </case>
   </cases>
</response>

答案 1 :(得分:1)

我能想到这样:

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

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <response>
        <cases>
            <xsl:apply-templates select="response/cases/case"/>
        </cases>
    </response>
</xsl:template>
<xsl:template match="cases/case">
    <xsl:variable name="pos" select="position()"/>
    <xsl:copy>
        <xsl:value-of select="."/>
        <xsl:copy-of select="//response/results/Final-Results[position() = $pos]/issues"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

答案 2 :(得分:1)

以下样式表会产生所需的结果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="case">
        <case>
            <xsl:value-of select="concat('&#xa;', ., '&#xa;')" />
            <xsl:copy-of
                select="../../results/Final-Results[
            count(current()/preceding-sibling::case) + 1]/issues" />
        </case>
    </xsl:template>
    <xsl:template match="results" />
</xsl:stylesheet>