У меня есть входной XML, как показано ниже:
<parent>
<payment>
<id>123456</id>
<type>CANCELLED</type>
<date>2020-12-03</date>
<amount>100</amount>
</payment>
<payment>
<id>234567</id>
<type>FORCE</type>
<date>2020-12-01</date>
<amount>200</amount>
</payment>
<payment>
<id>345678</id>
<type>CANCELLED</type>
<date>2020-12-01</date>
<amount>300</amount>
</payment>
<payment>
<id>456789</id>
<type>FORCE</type>
<date>2020-12-01</date>
<amount>400</amount>
</payment>
<payment>
<id>456788</id>
<type>CANCELLED</type>
<date>2020-12-01</date>
<amount>500</amount>
</payment>
</parent>
Теперь нам нужны узлы, где тип = «ОТМЕНЕН», и в этих отмененных платежах находится сложное условие, если дата равна, нам нужно выбрать узел с самым высоким идентификатором. Итак, в приведенном выше образце ввода должны быть выбраны только 1-й и 5-й узлы. дата для первого узла не совпадает ни с каким другим узлом, поэтому он выбран. В то время как дата для 5-го узла совпадает с 3-м узлом, но выбран 5-й, поскольку он имеет более высокий идентификатор.
Чтобы добиться этого, я попытался написать ниже XSLT,
<xsl:stylesheet version = "2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "xml" version = "1.0" encoding = "UTF-8" indent = "yes"/>
<xsl:strip-space elements = "*"/>
<xsl:variable name = "input" select = "parent"/>
<xsl:template match = "/">
<xsl:for-each select = "parent/payment[type='CANCELLED']">
<xsl:choose>
<xsl:when test = "date = $input/payment[type='CANCELLED']/date">
<xsl:message>
<xsl:value-of select = "amount"/>
</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select = "amount"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Для каждого требуется, так как в реальном примере мы извлекаем некоторые значения, поэтому нам нужно настроить условие цикла для каждого или написать условие внутри него. Я попытался объявить ввод переменной со всем входным xml и сравнить узел, который выбирается в рамках каждой итерации, с входным узлом, но затем он также совпадает с самим собой. Я иду в правильном направлении? Пожалуйста, направляйте.
Заранее спасибо.
Чтобы идентифицировать payment
с одинаковым date
, используйте группировку, затем в каждой группе выберите элемент (ы) с самым высоким/максимальным идентификатором:
<xsl:for-each-group select = "//payment[type = 'CANCELLED']" group-by = "date">
<xsl:copy-of select = "current-group()[id = max(current-group()/id)]"/>
</xsl:for-each-group>
Один последующий запрос: когда я делаю max(current-group()/id) , я теряю начальные нули. например, если идентификатор платежа 000004984, он становится 4984. Есть ли способ сохранить начальные нули и одновременно получить максимум?
@SwapnilPrabhavalkar, подумайте о том, чтобы задать новый вопрос с подробностями, все ли id
во входных данных имеют одинаковое количество цифр, можете ли вы жить с сравнением чисел, которое удаляет полосы ведущих нулей, но позволит вам позже использовать, например, `format-integer(max(current-group()/id), '0000000000') для форматирования максимального значения до желаемого количества цифр?
Спасибо @MartinHonnen. Я исправил проблему, используя номер формата, поскольку количество цифр было исправлено (10).
Спасибо @MartinHonnen. Идеальный !