【问题标题】:How to get root element tag only once under for each loop?如何在每个循环下仅获取一次根元素标记?
【发布时间】:2013-06-26 06:32:15
【问题描述】:

我需要为我的项目获取如下的最终输出结构 xml。但我在使用这段代码时遇到了一些问题。

<Endorsement>
    <TL>STNDBY/CHG FEE/NO RFND/</TL>
    <TL>CXL BY FLT DT/</TL>
</Endorsement>
<LText TopicId="MISCELLANEOUS">
    <TL>01 NVB28JUL/NVA28JUL</TL>
</LText>

这里是输入的xml文件

<InfoMsg>
    <AppNum>0</AppNum>
    <MsgType>2</MsgType>
    <Text>LAST DATE TO PURCHASE TICKET: 06JUN13</Text>
</InfoMsg>
<InfoMsg>
    <UniqueKey>0001</UniqueKey>
    <Lang>0</Lang>
    <Text>E-TKT REQUIRED</Text>
</InfoMsg>..............

为了实现上面的输出结构OI'使用下面的代码

<xsl:for-each select="../InfoMsg">
    <xsl:choose>
        <xsl:when test="MsgType='01' or MsgType='1'">
            <xsl:element name="Endorsement">
                <xsl:element name="TL">
                    <xsl:value-of select="Text"/>
                </xsl:element>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="LText">
                <xsl:attribute name="TopicId">
                    <xsl:text>MISCELLANEOUS</xsl:text>
                </xsl:attribute>
                <xsl:element name="TL">
                    <xsl:value-of select="Text"/>
                </xsl:element>
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:for-each>

这里的逻辑是,对于每个 Info Msg 标签,它应该检查 MSgType 是否等于 01 或 1,如果是,则创建 Endorsement 标签,否则它应该构造 Ltext 标签。条件是 Endorsement 元素中使用的 Msgtype 不应该重复在 Ltext 标签中。

但它给了我下面的输出

    - <Endorsement>
      <TL>STNDBY/CHG FEE/NO RFND/</TL> 
      </Endorsement>
    - <Endorsement>
      <TL>CXL BY FLT DT/</TL> 
      </Endorsement>
    - <LText TopicId="MISCELLANEOUS">
      <TL>01 NVB28JUL/NVA28JUL</TL> 
      </LText>
    - <LText TopicId="MISCELLANEOUS">
      <TL>02 NVB28JUL/NVA28JUL</TL> 
      </LText>
    - <LText TopicId="MISCELLANEOUS">
      <TL>LAST DATE TO PURCHASE TICKET: 26JUN13</TL> 
      </LText>
    - <LText TopicId="MISCELLANEOUS">
      <TL>E-TKT REQUIRED</TL> 
      </LText>
    - <LText TopicId="MISCELLANEOUS">
      <TL>ADDITIONAL TAXES, SURCHARGES, OR FEES MAY APPLY</TL> 
      </LText>

这里有多个背书标签 次,这是不必要的。它应该只来一次。

请建议我可以在我的代码中进行哪些更改以获得它。有没有其他方法或方法可以做到这一点。

谢谢 阿斯玛

【问题讨论】:

    标签: xml xslt foreach xsl-choose


    【解决方案1】:

    目前,您正在为您拥有的每个 InfoMsg 元素输出一个 Endorsement 元素(或 LText 元素),因此您得到如您所展示的重复元素。

    您需要做的只是输出 Endorsement 元素一次,然后在其中选择相关的 InfoMsg 元素。

    <Endorsement>
       <xsl:for-each select="InfoMsg[MsgType='01' or MsgType='1']">
          <TL>
              <xsl:value-of select="Text"/>
          </TL>
       </xsl:for-each>
    </Endorsement>
    

    Ltext 也是如此。

    注意这里没有真正需要使用xsl:element,直接输出元素即可。

    事实上,您可能应该在这里使用模板匹配,以允许您重用代码。试试这个 XSLT:

    <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="/*">
           <Endorsement>
               <xsl:apply-templates select="InfoMsg[MsgType='01' or MsgType='1']" />
           </Endorsement>
           <LText TopicId="MISCELLANEOUS">
               <xsl:apply-templates select="InfoMsg[not(MsgType='01' or MsgType='1')]" />
           </LText>
       </xsl:template>
    
       <xsl:template match="InfoMsg">
           <TL>
               <xsl:value-of select="Text"/>
           </TL>
       </xsl:template>
     </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-03
      • 2017-03-09
      • 2020-10-03
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      相关资源
      最近更新 更多