удалить дубликаты элементов в XML - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть большой файл, и я обнаружил, что некоторые элементы в нем есть дважды, теперь я хотел бы удалить дубликаты. какие-нибудь идеи, что я мог сделать? Буду признателен за любую помощь!

XML выглядит так:

<Toptag>
<text coordinates="" country="" date="yyyy-mm-dd" lang="" place="xyc" time="" id=" 123"  name="xyz" >
<div>
This is text
</div>
</text>
<text coordinates="" country="" date="yyyy-mm-dd" lang="" place="xyc" 
time="" id=" 124"  name="xyz" >
<div>
This is text
</div>
</text>
<text coordinates="" country="" date="yyyy-mm-dd" lang="" place="xyc"         time="" id=" 123"  name="xyz" >
<div>
This is text
</div>
</text>
....
</toptag>

В дубликатах все из <text...............> <div> </div> </text> точно такое же!

Спасибо !!!!!!

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Если вы можете определить функцию f: signature (element (text)), которая возвращает одинаковое значение для двух элементов тогда и только тогда, когда они считаются равными, вы можете использовать группировку XSLT 2.0 для устранения дубликатов:

<xsl:for-each-group select="text" group-by="f:signature(.)">
  <xsl:copy-of select="current-group()[1]"/>
</xsl:for-each-group>

Если элементы имеют очень разную структуру, тогда написание функции подписи может быть затруднено. Но если они все очень похожи, как показывает ваш пример, то вы можете использовать, например,

<xsl:function name="f:signature" as="xs:string">
  <xsl:param name="e" as="element(text)"/>
  <xsl:sequence select="string-join($e!(@coordinates, @country, @date, @lang, @place, string(.)), '|')"/>
</xsl:function>

Примечание: я использовал XSLT 3.0 "!" оператор, потому что вы не хотите, чтобы атрибуты сортировались в порядке документов (порядок документов в атрибутах непредсказуем). В 2.0, где "!" недоступно, вы можете записать это как ($e/@coordinates, $e/@country, $e/@date, ...).

0 голосов
/ 11 сентября 2018

Если вы используете хотя бы XSLT 2, у вас есть доступ к функции deep-equal https://www.w3.org/TR/xpath-functions/#func-deep-equal и, следовательно, вы можете написать пустой шаблон

  <xsl:template match="Toptag/text[some $sib in preceding-sibling::text satisfies deep-equal(., $sib)]"/>

вместе с преобразованием идентичности (например, в XSLT3, используя соответствующую декларацию xsl:mode или в XSLT 2, указав ее по буквам):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="Toptag/text[some $sib in preceding-sibling::text satisfies deep-equal(., $sib)]"/>

</xsl:stylesheet>

таким образом, те элементы text, у которых есть предыдущий брат или сестра text, которые глубоко равны, не копируются:https://xsltfiddle.liberty -development.net / 94hvTzF

Очевидно, что условие в предикате также можно настроить для проверки всех предыдущих узлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...