XSLT 1.0按顺序连接随机值

时间:2015-04-16 18:30:29

标签: loops xslt concatenation

我是XSLT的新手,我正在努力解决这个问题。我必须从XML中获取一些值并将它们连接起来。每当我尝试这样做时,我只获得一个值,但我希望结果中包含所有4个值。 XML值可以是任何顺序,但我只希望结果采用特定格式。结果应为Tag61值+ Tag9F01值+ Tag81值+ Tag4F值(请忽略+符号)。

请查看以下XML

<Transaction_details> 
<Transaction> 
<Detail> 
<tag>9F01</tag> 
<tag_value>9F01020001</tag_value>   
</Detail> 
<Detail> 
<tag>9F40</tag> 
<tag_value>9F40020001</tag_value>   
</Detail> 
<Detail> 
<tag>9F021</tag> 
<tag_value>9F021020001</tag_value>  
</Detail> 
<Detail> 
<tag>81</tag> 
<tag_value>81020001</tag_value> 
</Detail> 
<Detail> 
<tag>9F44</tag> 
<tag_value>9F44020001</tag_value>   
</Detail> 
<Detail> 
<tag>94</tag> 
<tag_value>94020001</tag_value> 
</Detail> 
<Detail> 
<tag>4F</tag> 
<tag_value>4F1020001</tag_value>    
</Detail> 
<Detail> 
<tag>61</tag> 
<tag_value>61020001</tag_value> 
</Detail> 
</Transaction>  
</Transaction_details> 

我写的代码

<xsl:for-each select="Transaction_details/Transaction"> 
<xsl:variable name="TAG"> 
<xsl:value-of select="Detail/tag"/> 
</xsl:variable> 
<xsl:variable name="TotalTags"> 
<xsl:variable name="Tag61"> 
<xsl:choose> 
<xsl:when test="$TAG='61'"> 
<xsl:value-of select="Detail/tag_value"/> 
</xsl:when> 
<xsl:otherwise> 
<xsl:value-of select="'No Data'"/> 
</xsl:otherwise>    
</xsl:choose> 
</xsl:variable> 
<xsl:variable name="Tag9F01"> 
<xsl:choose> 
<xsl:when test="$TAG='9F01'"> 
<xsl:value-of select="Detail/tag_value"/> 
</xsl:when> 
<xsl:otherwise> 
<xsl:value-of select="'No Data'"/> 
</xsl:otherwise>    
</xsl:choose> 
</xsl:variable> 
<xsl:variable name="Tag81"> 
<xsl:choose> 
<xsl:when test="$TAG='81'"> 
<xsl:value-of select="Detail/tag_value"/> 
</xsl:when> 
<xsl:otherwise> 
<xsl:value-of select="'No Data'"/> 
</xsl:otherwise>    
</xsl:choose> 
</xsl:variable> 
<xsl:variable name="Tag4F"> 
<xsl:choose> 
<xsl:when test="$TAG='4F'"> 
<xsl:value-of select="Detail/tag_value"/> 
</xsl:when> 
<xsl: otherwise> 
<xsl:value-of select="'No Data'"/> 
</xsl:otherwise>    
</xsl:choose> 
</xsl:variable> 
<xsl:value-of select="concat($Tag61,$Tag9F01,$Tag81,$Tag4F)"/>  
</xsl:variable> 
</xsl:for-each> 

在此代码之后,当我连接值时,我只得到1个值。 我正在使用XSLT 1.0。有人可以建议如何达到预期的效果。哪一个好的选项递归模板或for_each来解决这个问题?

提前谢谢你,

Kaushik

2 个答案:

答案 0 :(得分:1)

要突出显示XSLT的几个问题,您可以在一个问题中定义TAG变量

<xsl:variable name="TAG"> 
    <xsl:value-of select="Detail/tag"/> 
</xsl:variable> 

这会将TAG设置为仅包含第一个Detail/tag值的单个字符串。你可能应该这样做

<xsl:variable name="TAG" select="Detail/tag"/> 

然后将TAG设置为所有Detail/tag条记录的节点集。

同样,当你做测试时,你做了这个

<xsl:when test="$TAG='61'"> 
    <xsl:value-of select="Detail/tag_value"/> 
</xsl:when> 

这将仅输出第一个Detail/tag_value值,而不是标记61的值。

但为了简短起见,您的XSLT最初可以重写为

<xsl:template match="Transaction_details/Transaction">
    <xsl:apply-templates select="Detail[tag='61']/tag_value" />
    <xsl:apply-templates select="Detail[tag='9F01']/tag_value" />
    <xsl:apply-templates select="Detail[tag='81']/tag_value" />
    <xsl:apply-templates select="Detail[tag='4F']/tag_value" />
</xsl:template>

请注意,这里实际上不需要匹配tag_value的模板,因为内置模板只会用于输出文本。

这仅在标签始终存在时才有效。虽然您在问题中没有实际提及它,但如果标签不存在,您似乎想输出“无数据”。

要做到这一点,并避免重复编码,您可以使用命名模板。也试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="text" indent="yes" />

    <xsl:template match="Transaction_details/Transaction">
        <xsl:call-template name="TagValue"><xsl:with-param name="tag" select="'61'" /></xsl:call-template>
        <xsl:call-template name="TagValue"><xsl:with-param name="tag" select="'9F01'" /></xsl:call-template>
        <xsl:call-template name="TagValue"><xsl:with-param name="tag" select="'81'" /></xsl:call-template>
        <xsl:call-template name="TagValue"><xsl:with-param name="tag" select="'4F'" /></xsl:call-template>
    </xsl:template>

    <xsl:template name="TagValue">
        <xsl:param name="tag" />
        <xsl:variable name="value" select="Detail[tag=$tag]/tag_value" />
        <xsl:value-of select="$value" />
        <xsl:if test="not($value)">No Data</xsl:if>
    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

  

请忽略我写的代码。你能建议我吗?   一些代码会给我连接的tag_value节点值   标签61,9F01,81和4F?

您的问题仍然不太明确,但如果您想将所有tag_value的{​​{1}}值标记为4个列出的标记之一,您可以非常简单地通过:

XSLT 1.0

Detail

示例中的结果将是:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" encoding="utf-8"/>

<xsl:template match="/Transaction_details">
    <xsl:for-each select="Transaction/Detail[tag='61' or tag='9F01' or tag='81' or tag='4F']" >
        <xsl:value-of select="tag_value"/>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>