XSL удаляет дублирующиеся элементы не работает (оставляя пустой родительский элемент) - PullRequest
0 голосов
/ 09 января 2020

У меня есть это xml.

<list>
<message ref="00001">
    <entry>
        <orderid>P001</orderid>
        <timestamp>20200109085816092</timestamp>
    </entry>
</message>
<message ref="00002">
    <entry>
        <orderid>P002</orderid>
        <timestamp>20200109085813556</timestamp>
    </entry>
</message>
<message ref="00003">
    <entry>
        <orderid>P003</orderid>
        <timestamp>20200109085814612</timestamp>
    </entry>
</message>
<message ref="00004">
    <entry>
        <orderid>P001</orderid>
        <timestamp>20010109085816092</timestamp>
    </entry>
</message>
<message ref="00005">
    <entry>
        <orderid>P002</orderid>
        <timestamp>20020109085813556</timestamp>
    </entry>
</message>
<message ref="00006">
    <entry>
        <orderid>P003</orderid>
        <timestamp>20030109085814612</timestamp>
    </entry>
</message>

Мне нужно удалить узлы "сообщения", когда существует еще один узел с таким же "orderid" (проверка дубликатов). Я использую этот xsl.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="kOrderId" match="entry" use="orderid"/>

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

<xsl:template match="entry[not(generate-id() = generate-id(key('kOrderId', orderid)[1]))]"/>

Но вывод содержит нежелательные теги "message" (с ref = "0004", "0005" и "0006").

<list>
<message ref="00001">
    <entry>
        <orderid>P001</orderid>
        <timestamp>20200109085816092</timestamp>
    </entry>
</message>
<message ref="00002">
    <entry>
        <orderid>P002</orderid>
        <timestamp>20200109085813556</timestamp>
    </entry>
</message>
<message ref="00003">
    <entry>
        <orderid>P003</orderid>
        <timestamp>20200109085814612</timestamp>
    </entry>
</message>
<message ref="00004"/>
<message ref="00005"/>
<message ref="00006"/>

Мне нужно удалить эти дополнительные теги из вывода. Как мне этого добиться? Спасибо.

1 Ответ

1 голос
/ 09 января 2020

Если вы хотите удалить дубликаты message элементов, сделайте так, чтобы ваш ключ и шаблон соответствовали message, а не entry:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="kOrderId" match="message" use="entry/orderid"/>

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

<xsl:template match="message[not(generate-id() = generate-id(key('kOrderId', entry/orderid)[1]))]"/>

</xsl:stylesheet>

Обратите внимание, что это предполагает, что message содержит одноместный entry,

...