XSLT сравнивает значение элемента из разных узлов - проблема производительности - PullRequest
1 голос
/ 18 июня 2020

Есть ли лучший способ, чем два цикла for, для сборки узловых элементов для следующей XML структуры набора данных / XML?

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <nodeA>
        <nodeAa>
            <Row>
                <ID>100001</ID>
                <NAME>ABC</NAME>
                <EDV_NUMBER>900001</EDV_NUMBER>
            </Row>
            <Row>
                <ID>100002</ID>
                <NAME>DEF</NAME>
                <EDV_NUMBER>900002</EDV_NUMBER>
            </Row>
            <Row>
                <ID>700003</ID>
                <NAME>XYZ</NAME>
                <EDV_NUMBER>900002</EDV_NUMBER>
            </Row>
        </nodeAa>
    </nodeA>
    <nodeB>
        <nodeBa>
            <Row>
                <EDV_NUMBER>900001</EDV_NUMBER>
                <TYP>002</TYP>
            <Row>
                <EDV_NUMBER>900002</EDV_NUMBER>
                <TYP>002</TYP>
            </Row>
            <Row>
                <EDV_NUMBER>900002</EDV_NUMBER>
                <TYP>009</TYP>
            </Row>
        </nodeBa>
    </nodeB>
</root>

Выходной файл должен содержать все элементы узла «// nodeBa / Row / *», включая элементы (ID и NAME) узла «// nodeAa / Row /», где элемент «EDV_NUMBER» одинаков.

<?xml version="1.0" encoding="UTF-8"?>
<CSV>
    <Row>
        <EDV_NUMBER>900001</EDV_NUMBER>
        <TYP>002</TYP>
        <ID>100001</ID>
        <NAME>ABC</NAME>
    </Row>
    <Row>
        <EDV_NUMBER>900002</EDV_NUMBER>
        <TYP>002</TYP>
        <ID>100002</ID>
        <NAME>DEF</NAME>
    </Row>
    <Row>
        <EDV_NUMBER>900002</EDV_NUMBER>
        <TYP>009</TYP>
        <ID>700003</ID>
        <NAME>XYZ</NAME>
    </Row>
</CSV>

Результат может быть сгенерирован с помощью следующего кода, но не работает для больших наборов данных:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="#all" version="2.0">
  <xsl:output method="xml" encoding="UTF-8"/>  
     <xsl:template match="/">
     <CSV>
          <xsl:for-each select="/root/nodeB/nodeBa/Row">

               <xsl:variable name="FIBU" select="./EDV_NUMBER/text()"/>
               <xsl:variable name="TYP" select="./TYP/text()"/>     

               <Row select="{position()}">
                    <xsl:copy-of select="./*"/>

                    <xsl:for-each select="/root/nodeA/nodeAa/Row">
                    <xsl:variable name="counter" select="position()"/>  
                         <xsl:choose>
                              <xsl:when test="/root/nodeA/nodeAa/Row[$counter]/EDV_NUMMER/text()=$FIBU and $TYP='002' and /root/nodeA/nodeAa/Row[$counter]/TYP/text() &lt; '700000'">
                                   <xsl:copy-of select="./ID"/>
                                   <xsl:copy-of select="./NAME"/>
                              </xsl:when>
                              <xsl:when test="/root/nodeA/nodeAa/Row[$counter]/EDV_NUMMER/text()=$FIBU and $TYP='009' and /root/nodeA/nodeAa/Row[$counter]/TYP/text() &gt;= '700000'">
                                   <xsl:copy-of select="./ID"/>
                                   <xsl:copy-of select="./NAME"/>
                              </xsl:when>
                              <xsl:otherwise/>
                         </xsl:choose>
                    </xsl:for-each>
               </Row>
          </xsl:for-each>
     </CSV>
     </xsl:template>
</xsl:stylesheet>

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Кажется, вы хотите объявить ключ <xsl:key name="nodea-ref" match="nodeA/nodeAa/Row" use="EDV_NUMMER"/>, а затем использовать <xsl:copy-of select="key('nodea-ref', EDV_NUMMER)/(ID, NAME)"/> внутри внешнего for-each.

1 голос
/ 18 июня 2020

попробуйте заменить внутренний l oop на что-то вроде этого: он выберет все узлы в / root / nodeA с тем же EDV_NUMBER, что и текущий элемент внешнего l oop

<xsl:when test="/root/nodeA/nodeAa/Row[EDV_NUMBER=$FIBU]">
<!-- ... -->
</xsl:when>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...