XSLT: удаление элементов с дублирующимися значениями атрибутов - PullRequest
1 голос
/ 11 декабря 2019

У меня есть xml, и я хочу удалить элементы (Elephant), которые имеют повторяющиеся значения атрибутов дочернего элемента (Cost) (доллары и центы равны элементам-братьям) и оставить только один элемент (Elephant).

Исходный xml (это всего лишь фрагмент полного документа):

<?xml version="1.0" encoding="UTF-8"?>
   <Day>      
         <Queue id="460402">
            <Time>4</Time>
            <Elephant>
               <Cost dollars="14" cents="5" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="6" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="1" cents="46" />
            </Elephant>
            <Elephant>
               <Cost dollars="55" cents="5" />
            </Elephant>
         </Queue>
         <Queue id="460404">
            <Time>3</Time>
            <Elephant>
               <Cost dollars="7" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="7" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="7" cents="2" />
            </Elephant>
            <Elephant>
               <Cost dollars="7" cents="2" />
            </Elephant>
            <Elephant>
               <Cost dollars="114" cents="5" />
            </Elephant>
         </Queue>
         <Queue id="4666047">
            <Time>7</Time>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
         </Queue>      
   </Day>

Ожидаемый результат:

<?xml version="1.0" encoding="UTF-8"?>
   <Day>      
         <Queue id="460402">
            <Time>4</Time>
            <Elephant>
               <Cost dollars="14" cents="5" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="14" cents="6" />
            </Elephant>           
            <Elephant>
               <Cost dollars="1" cents="46" />
            </Elephant>
            <Elephant>
               <Cost dollars="55" cents="5" />
            </Elephant>
         </Queue>
         <Queue id="460404">
            <Time>3</Time>
            <Elephant>
               <Cost dollars="7" cents="1" />
            </Elephant>
            <Elephant>
               <Cost dollars="7" cents="2" />
            </Elephant>
            <Elephant>
               <Cost dollars="114" cents="5" />
            </Elephant>
         </Queue>
         <Queue id="4666047">
            <Time>7</Time>
            <Elephant>
               <Cost dollars="14" cents="1" />
            </Elephant>
         </Queue>      
   </Day>

Я попытался запустить это преобразование xslt, но оно не работает должным образом (больше данныхотсутствует, чем должно быть):

<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:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Elephant[Cost/@dollars= following-sibling:: Elephant/Cost/@dollars and Cost/@cents= following-sibling:: Elephant/Cost/@cents]"/>
</xsl:stylesheet>

1 Ответ

0 голосов
/ 12 декабря 2019

Нашли решение:

<?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"
    exclude-result-prefixes="#all"
    version="2.0">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

  <xsl:template match="Queue">
      <xsl:copy>
          <xsl:apply-templates select="*[not(self::Elephant)]|@*"/>
          <xsl:for-each-group select="Elephant" group-by="Cost/(@dollars + 0.01 * @cents)">
              <xsl:apply-templates select="."/>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
...