Условный XSL для каждого цикла в XSL для каждого - PullRequest
0 голосов
/ 21 мая 2018

У меня есть сценарий, где мне нужно сгенерировать xml с newnode1, используя XSLT, читая 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: для каждого внутри другого xsl: для каждого и условие if для проверки номера строки каждый раз, когда xsl: для каждого выполняется .. Есть липростая логика, чтобы получить мой результат, кроме того, что я пытался.

Заранее спасибо.

1 Ответ

0 голосов
/ 21 мая 2018

Одна из ваших проблем заключается в том, как вы определяете переменную line

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

. При этом выбираются все элементы Line из всех элементов Node_1 в вашем XML.Это означает, что когда вы делаете <xsl:if test="Line=$line">, это на самом деле будет возвращать true независимо от того, что Node_1 вы обрабатываете, таким образом вы будете выводить все 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> 

(Примечание,Я добавил создание тегов node и subnode, чтобы было легче видеть правильные Node_2 элементы, связанные с каждым Node_1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...