我有这个XML文件:
<?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>
在此发布之后,我正在尝试使用<d:index
删除条目的重复XSLT
:https://stackoverflow.com/a/56898207/589924
注意:每个条目都有自己独立的
<d:index
,即相同的索引 在不同条目中不应视为重复项。并且生成的xml应该采用原始xml格式。
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
内容之外的所有标签。
<?xml version="1.0"?>
This is the content for entry.
This is the content for entry.
答案 0 :(得分:3)
使用Muenchian method for grouping :
<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>
答案 1 :(得分:1)
有时使用直接编程的库可能会更容易。 使用XML :: DT
跟随Perl脚本#!/usr/bin/perl
use XML::DT;
my $filename = shift;
my %seen=();
my %handler=(
'd:entry' => sub{ %seen=(); toxml }, ## reset seen
'd:index' => sub{ if ($seen{$v{"d:value"}}++){"" } ## $v{id} -- attribute id
else {toxml}},
);
print dt($filename, %handler);
通常,sudo cpan XML::DT
(如果未安装)。