@AnotherAnkor

Как динамически добавлять блоки или изменять значения полей при использовании xslt?

На руках примеры xml и неизвестно откуда взявшаяся xslt.
Мне нужно иметь несколько больше свободы в своих действиях и хотелось бы:
  • иметь возможность создавать параметром заданное значение (у меня это количество банковских операций)
  • иметь возможность влиять на содержимое (дебет с кредитом в этих операциях должны сойтись)

Я использовал для работы с xslt saxon и обёртку, которую нашёл на codeproject. Но эта связка отлично справляется с шаблонными преобразованиями, но не с описанной мною задачей (я не нашёл нигде упоминания о такой возможности).
А существует ли она вообще? А если очень надо, то как быть?
UPD (примеры):
Входная xml (нам ничем не поможет) рассказывает нам, для какого счёта вернуть данные по операциям.

Выходная xml:
<?xml version="1.0" encoding="UTF-8"?>
<Statement xmlns="http://ююю"
           xmlns:a="urn:iso:std:iso:20022:tech:xsd:camt.053.001.04">
   <acceptDate>2018-11-28T13:23:43</acceptDate>
   <account>88888888888888888888</account>
   <bankBIC>5555555555</bankBIC>
   <creditReturn>1600000.00</creditReturn>
   <creditReturnNat>1600000.00</creditReturnNat>
   <currCode>RUB</currCode>
   <debetReturn>0.00</debetReturn>
   <debetReturnNat>0.00</debetReturnNat>
   <externalId>ABC59913</externalId>
   <docDate>2018-11-28T13:23:43</docDate>
   <fromDate>2018-11-28T00:00:00</fromDate>
   <isFinal>1</isFinal>
   <toDate>2018-11-28T00:00:00</toDate>
   <inboundBalance>2296351.83</inboundBalance>
   <inboundBalanceNat/>
   <outboundBalance>3896351.83</outboundBalance>
   <outboundBalanceNat/>
   <operations>
      <Operation>
         ....
      </Operation>
   </operations>
</Statement>

Выходная формируется на основании xslt 2.0
Блок Operation должен повторяться произвольное количество раз, а не как в предоставленном мне xslt (который я не могу предоставить из-за nda) - 4 раза. Отдельные поля в Operation тоже должны быть заполнены мной.
То есть мне нужно повлиять на количество операций и значения полей в операциях.
  • Вопрос задан
  • 129 просмотров
Решения вопроса 1
@Roman-Fov
Раз для теста, то можно однотипные данные писать

data.xml
<?xml version="1.0"?>
<root>
<foo/>
</root>


proc.xsl с рекурсией
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <operations>
            <xsl:call-template name="operation">
                <xsl:with-param name="counter" select="5"/>
            </xsl:call-template>
        </operations>
    </xsl:template>

    <xsl:template name="operation">
        <xsl:param name="counter" select="1"/>

        <operation>
            <name>
                <xsl:text>Ivan</xsl:text>
                <xsl:value-of select="$counter"/>
            </name>
            <price>
                <xsl:value-of select="100 * $counter"/>
            </price>
        </operation>

        <xsl:if test="$counter > 0">
            <xsl:call-template name="operation">
                <xsl:with-param name="counter" select="$counter - 1"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>


xsltproc proc.xsl data.xml > result.xml
cat result.xml


<?xml version="1.0"?>
<operations>
  <operation>
    <name>Ivan5</name>
    <price>500</price>
  </operation>
  <operation>
    <name>Ivan4</name>
    <price>400</price>
  </operation>
  <operation>
    <name>Ivan3</name>
    <price>300</price>
  </operation>
  <operation>
    <name>Ivan2</name>
    <price>200</price>
  </operation>
  <operation>
    <name>Ivan1</name>
    <price>100</price>
  </operation>
  <operation>
    <name>Ivan0</name>
    <price>0</price>
  </operation>
</operations>


или для второй версии на циклах
proc.xsl
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <operations>
            <xsl:for-each select="1 to 10">
                <operation>
                    <name>
                        <xsl:text>Ivan</xsl:text>
                        <xsl:value-of select="position()"/>
                    </name>
                    <price>
                        <xsl:value-of select="100 * position()"/>
                    </price>
                </operation>
            </xsl:for-each>
        </operations>
    </xsl:template>
</xsl:stylesheet>


saxonb-xslt -s:data.xml -xsl:proc.xsl -o:result.xml
cat result.xml

<?xml version="1.0" encoding="UTF-8"?>
<operations>
   <operation>
      <name>Ivan1</name>
      <price>100</price>
   </operation>
   <operation>
      <name>Ivan2</name>
      <price>200</price>
   </operation>
   <operation>
      <name>Ivan3</name>
      <price>300</price>
   </operation>
   <operation>
      <name>Ivan4</name>
      <price>400</price>
   </operation>
   <operation>
      <name>Ivan5</name>
      <price>500</price>
   </operation>
   <operation>
      <name>Ivan6</name>
      <price>600</price>
   </operation>
   <operation>
      <name>Ivan7</name>
      <price>700</price>
   </operation>
   <operation>
      <name>Ivan8</name>
      <price>800</price>
   </operation>
   <operation>
      <name>Ivan9</name>
      <price>900</price>
   </operation>
   <operation>
      <name>Ivan10</name>
      <price>1000</price>
   </operation>
</operations


Это оно? Так хотели генерировать их?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы