Как скопировать значения путем сопоставления узлов в XSLT - PullRequest
0 голосов
/ 04 июля 2019

В моем XML я хочу скопировать значения в один узел из другого узла, если оба узла имеют совпадающие значения в некоторых других узлах.

<XML>
    <ORG>
        <ITM>
            <NUM>1</NUM>
            <SEQ>10</SEQ>
            <VAL>X</VAL>
        </ITM>
        <ITM>
            <NUM>2</NUM>
            <SEQ>20</SEQ>
            <VAL>Y</VAL>
        </ITM>
    </ORG>
    <NEW>
        <ITM>
            <NUM>1</NUM>
            <SEQ>10</SEQ>
            <VAL>QQQ</VAL>
        </ITM>
    </NEW>
</XML>

Это работает, но для больших документов это может быть медленным, есть ли лучший способ?

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

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


    <xsl:template match="ORG/ITM/VAL">
        <xsl:variable name="NUM" select="../NUM"/>
        <xsl:variable name="SEQ" select="../SEQ"/>
        <VAL>
            <xsl:value-of select="../../../NEW/ITM/VAL[../NUM=$NUM and ../SEQ=$SEQ]"/>
        </VAL>
    </xsl:template>
</xsl:stylesheet>

Результат имеет значение "QQQ" в узле ORG / ITM / VAL, поскольку ORG / ITM / NUM и ORD / ITM / SEQ совпадают с NEW / ITM / NUM и NEW / ITM / SEQ

<?xml version="1.0"?>
<XML>
    <ORG>
        <ITM>
            <NUM>1</NUM>
            <SEQ>10</SEQ>
            <VAL>QQQ</VAL>
        </ITM>
        <ITM>
            <NUM>2</NUM>
            <SEQ>20</SEQ>
            <VAL/>
        </ITM>
    </ORG>
    <NEW>
        <ITM>
            <NUM>1</NUM>
            <SEQ>10</SEQ>
            <VAL>QQQ</VAL>
        </ITM>
    </NEW>
</XML>

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

Предпочтительный метод поиска значений - определить ключ и использовать его. В приведенном примере это может быть:

XSLT 1.0

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

<xsl:key name="new-item" match="NEW/ITM" use="concat(NUM, '|', SEQ)" />

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

<xsl:template match="ORG/ITM/VAL">
    <xsl:copy>
         <xsl:value-of select="key('new-item', concat(../NUM, '|', ../SEQ))/VAL"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
0 голосов
/ 04 июля 2019

с использованием 1 переменной быстрее.

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

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


    <xsl:template match="ORG/ITM/VAL">
        <xsl:variable name="NUMSEQ" select="concat(string(../NUM), string(../SEQ))"/>        
        <VAL>
            <xsl:value-of select="../../../NEW/ITM/VAL[concat(string(../NUM), string(../SEQ))=$NUMSEQ]"/>
        </VAL>
    </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...