XSL中每个循环的条件XSL

时间:2018-05-21 06:06:18

标签: xml xslt db2

我有这样的场景,我需要使用XSLT通过读取xn node1来生成xml,该xml node1可以传递'n'次,而node2也可以传递'n'次。 这是我的xml的样子..

     <?xml version="1.0" encoding="UTF-8"?>
    <Node>
    <Node_1>
       <Line>1</Line>
       <Text>First node1</Text>
       <Desc>Desc1</Desc>
       <Cust>Cust1</Cust>
    </Node_1>
    <Node_1>
       <Line>2</Line>
       <Text>First node2</Text>
       <Desc>Desc2</Desc>
       <Cust>Cust2</Cust>
    </Node_1>
    <Node_2>
       <Line>1</Line>
       <ReadInd>Y</ReadInd>
       <WriteInd>Y</WriteInd>
       <UpdateInd>Y</UpdateInd>
    </Node_2>
    <Node_2>
       <Line>2</Line>
       <ReadInd>N</ReadInd>
       <WriteInd>N</WriteInd>
       <UpdateInd>N</UpdateInd>
    </Node_2>
    </Node>        

下面是我为此实现的XSLT代码,但我确实看到了运行时的性能问题,我的输入XML Node_1和Node_2重复超过100个循环需要更多时间。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version = "1.0"   
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">     
<xsl:template match = "/">   
<xsl:for-each select="Node/Node_1">
    <xsl:variable name="line" select="//Node_1/Line"/>
    <line><xsl:value-of select="Line"/></line>
    <text><xsl:value-of select="Text"/></text>
    <desc><xsl:value-of select="Desc"/></desc>
    <cust><xsl:value-of select="Cust"/></cust>
    <xsl:for-each select="/Node/Node_2">
        <xsl:if test="Line=$line">
            <readind><xsl:value-of select="ReadInd"/></readind>
            <writeind><xsl:value-of select="WriteInd"/></writeind>
            <updateind><xsl:value-of select="UpdateInd"/></updateind>
        </xsl:if>
    </xsl:for-each>
</xsl:for-each>
</xsl:template>    
</xsl:stylesheet> 

正如你所看到的,我已经使用了xsl:for each in xsl:for each,以及if条件来检查每次xsl:for每次执行时的行号。是否有一个简单的逻辑来获取我的结果,除了我尝试的。

提前致谢。

1 个答案:

答案 0 :(得分:0)

您遇到的一个问题是如何定义line变量

<xsl:variable name="line" select="//Node_1/Line"/>

这将选择XML中所有Line元素下的所有Node_1元素。这意味着当您执行<xsl:if test="Line=$line">时,无论您正在处理什么Node_1,这都会返回true,因此您将输出所有Node_2个元素。

您应该像这样定义

但是,为了有效查找,请考虑使用密钥

<xsl:key name="node2" match="Node_2" use="Line" />

然后你可以像这样选择Node_2元素

<xsl:for-each select="key('node2', $line)">

或者甚至是这样,因为在这种情况下不需要变量,因为此时当前节点仍然是Node_1

<xsl:for-each select="key('node2', Line)">

试试这个XSLT

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

<xsl:key name="node2" match="Node_2" use="Line" />

<xsl:template match="/">   
    <xsl:for-each select="Node/Node_1">
        <node>
        <line><xsl:value-of select="Line"/></line>
        <text><xsl:value-of select="Text"/></text>
        <desc><xsl:value-of select="Desc"/></desc>
        <cust><xsl:value-of select="Cust"/></cust>
        <xsl:for-each select="key('node2', Line)">
            <subnode>
            <readind><xsl:value-of select="ReadInd"/></readind>
            <writeind><xsl:value-of select="WriteInd"/></writeind>
            <updateind><xsl:value-of select="UpdateInd"/></updateind>
            </subnode>
        </xsl:for-each>
        </node>
    </xsl:for-each>
</xsl:template>    
</xsl:stylesheet> 

(注意,我添加了nodesubnode标记的创建,以便更容易看到与每个Node_2相关联的正确Node_1元素