Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
删除xml中的重复元素_Xml_Xslt_Xpath - Fatal编程技术网

删除xml中的重复元素

删除xml中的重复元素,xml,xslt,xpath,Xml,Xslt,Xpath,我有一个大文件,发现其中有两个元素,现在我想删除重复的。你知道我能做什么吗?非常感谢您的帮助 xml如下所示: <Toptag> <text coordinates="" country="" date="yyyy-mm-dd" lang="" place="xyc" time="" id=" 123" name="xyz" > <div> This is text </div> </text> <text coordinate

我有一个大文件,发现其中有两个元素,现在我想删除重复的。你知道我能做什么吗?非常感谢您的帮助

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>

这是文本
这是文本
这是文本
....
在副本中,
中的所有内容都完全相同


谢谢你

假设您至少使用XSLT 2,您可以访问
deep equal
函数,因此可以编写一个空模板

  <xsl:template match="Toptag/text[some $sib in preceding-sibling::text satisfies deep-equal(., $sib)]"/>
这样,就不会复制具有深度相等的前一个同级
text
text
元素:


显然,谓词中的条件也可以调整为检查所有前面的节点。

假设您至少使用XSLT 2,您可以访问
deep equal
函数,因此可以编写空模板

  <xsl:template match="Toptag/text[some $sib in preceding-sibling::text satisfies deep-equal(., $sib)]"/>
这样,就不会复制具有深度相等的前一个同级
text
text
元素:


显然,谓词中的条件也可以调整以检查所有前面的节点。

如果您可以定义一个函数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,…)

如果您可以定义一个函数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,…)

OP说它是一个大文件:这将是一个O(n^2),这不太好。我想我需要先在XML暑期学校学习XSLT性能课程,然后再在StackOverflow上构思出外观优雅的东西。我读过的一些人经常对我们说,如果出现问题,只担心性能,所以让我们听听海报上的话。谢谢你的帮助!它在较小的文件上运行得非常好。。。在更大的文件(500mb-1gb)上花费了很长时间(在完成之前我不得不取消它)。再次感谢@mynamehere,您到底使用哪种XSLT处理器和版本?正如Michael Kay所指出的,我上面关于兄弟姐妹的建议不适用于大文件,您需要尝试实现他的建议,尽管根据您的系统,使用1GB大文件时,您可能会遇到传统的、基于树的XSLT的限制。@mynamehere,昨天,我尝试在上实现Mike的建议,尽管这是一个黑客行为,因为我只是简单地使用了
序列化
,而不是使用自定义指纹函数来确保属性的顺序相同。也许这有助于你将他的建议塑造成一个适用于大文件的工作解决方案。OP说这是一个大文件:这将是一个O(n^2),这不是很好。我想我需要先在XML暑期学校学习XSLT性能课程,然后再在StackOverflow上构思一些外观优雅的东西。我读过的一些人经常对我们说,如果出现问题,只担心性能,所以让我们听听海报上的话。谢谢你的帮助!它在较小的文件上运行得非常好。。。在更大的文件(500mb-1gb)上花费了很长时间(在完成之前我不得不取消它)。再次感谢@mynamehere,您到底使用哪种XSLT处理器和版本?正如Michael Kay所指出的,我上面关于兄弟姐妹的建议不适用于大文件,您需要尝试实现他的建议,尽管根据您的系统,使用1GB大文件时,您可能会遇到传统的、基于树的XSLT的限制。@mynamehere,昨天,我尝试在上实现Mike的建议,尽管这是一个黑客行为,因为我只是简单地使用了
序列化
,而不是使用自定义指纹函数来确保属性的顺序相同。也许这有助于你将他的建议塑造成一个大文件的有效解决方案,也许你正试图用XSLT1.0处理器来运行它。当事情不起作用时,我们通常无法帮助您,除非您解释故障症状。也许您正在尝试使用XSLT1.0处理器运行它。当事情不起作用时,我们通常无法帮助你,除非你解释失败的症状。