使用 XSLT 和 perl XML::LibXSLT 删除重复的 XML 元素 [英] Remove duplicate XML elements using XSLT with perl XML::LibXSLT

查看:33
本文介绍了使用 XSLT 和 perl XML::LibXSLT 删除重复的 XML 元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个 XML 文件:

I have this XML file:

<?xml version="1.0" encoding="UTF-8"?>
<d:dictionary xmlns="http://www.w3.org/1999/xhtml" xmlns:d="http://www.apple.com/DTDs/DictionaryService-1.0.rng">
    <d:entry id="a" d:title="a">
        <d:index d:value="a" d:title="a"/>
        <d:index d:value="b" d:title="b"/>
        <d:index d:value="a" d:title="a"/>
        <d:index d:value="c" d:title="c"/>
        <d:index d:value="b" d:title="b"/>
        <d:index d:value="a" d:title="a"/>
        <d:index d:value="b" d:title="b"/>
        <div>This is the content for entry.</div>
    </d:entry>
    <d:entry id="b" d:title="b">
        <d:index d:value="a" d:title="a"/>
        <d:index d:value="b" d:title="b"/>
        <div>This is the content for entry.</div>
    </d:entry>
</d:dictionary>

我正在尝试使用 XSLT 删除重复的 <d:index 条目,如下此帖子:https://stackoverflow.com/a/56898207/589924

I'm trying to remove the duplicate <d:index of the entries using XSLT following this posting: https://stackoverflow.com/a/56898207/589924

注意:每个条目都有自己独立的<d:index,即相同的索引在不同的条目中不应算作重复.并且生成的 xml 应遵循原始 xml 格式.

Note: Every entry have its own independent <d:index, i.e. same index in different entries should not count as a duplicate. And the resulting xml should honor the original xml format.

xsl 文件是这样的:

<xsl:stylesheet version="2.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:d="http://www.apple.com/DTDs/DictionaryService-1.0.rng">
<xsl:template>
    <xsl:copy>
        <xsl:for-each-group select="d:index"
                            group-by="concat(@d:value, '~', @d:title)">
            <xsl:copy-of select="current-group()[1]"/>
        </xsl:for-each-group>
        <xsl:copy-of select="div"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

但结果不是预期的,它删除了除div内容之外的所有标签.

But the result is not expected, it removes all tags except for the content of div.

<?xml version="1.0"?>









This is the content for entry.




This is the content for entry.

推荐答案

使用 Muenchian 分组方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:d="http://www.apple.com/DTDs/DictionaryService-1.0.rng" exclude-result-prefixes="d">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:key name="kIndexByValueTitle" match="d:index"
          use="concat(generate-id(..), '+', @d:value, '+', @d:title)"/>

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

  <xsl:template match=
   "d:index[not(generate-id()
               = generate-id(key('kIndexByValueTitle',
                                  concat(generate-id(..), '+', @d:value, '+', @d:title)
                                 )
                                  [1]))]" />
</xsl:stylesheet>

对提供的 XML 文档应用此转换时:

<d:dictionary xmlns="http://www.w3.org/1999/xhtml"
 xmlns:d="http://www.apple.com/DTDs/DictionaryService-1.0.rng">
    <d:entry id="a" d:title="a">
        <d:index d:value="a" d:title="a"/>
        <d:index d:value="b" d:title="b"/>
        <d:index d:value="a" d:title="a"/>
        <d:index d:value="c" d:title="c"/>
        <d:index d:value="b" d:title="b"/>
        <d:index d:value="a" d:title="a"/>
        <d:index d:value="b" d:title="b"/>
        <div>This is the content for entry.</div>
    </d:entry>
    <d:entry id="b" d:title="b">
        <d:index d:value="a" d:title="a"/>
        <d:index d:value="b" d:title="b"/>
        <div>This is the content for entry.</div>
    </d:entry>
</d:dictionary>

产生想要的、正确的结果:

<d:dictionary xmlns:d="http://www.apple.com/DTDs/DictionaryService-1.0.rng" xmlns="http://www.w3.org/1999/xhtml">
   <d:entry id="a" d:title="a">
      <d:index d:value="a" d:title="a"/>
      <d:index d:value="b" d:title="b"/>
      <d:index d:value="c" d:title="c"/>
      <div>This is the content for entry.</div>
   </d:entry>
   <d:entry id="b" d:title="b">
      <d:index d:value="a" d:title="a"/>
      <d:index d:value="b" d:title="b"/>
      <div>This is the content for entry.</div>
   </d:entry>
</d:dictionary>

这篇关于使用 XSLT 和 perl XML::LibXSLT 删除重复的 XML 元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆