我希望在一个xml文件中返回具有相同文本值的重复节点

时间:2018-05-31 09:25:09

标签: xquery marklogic

在我的xml下面:

文件名: relation.xml

    <relations>
<relation>
<normativelyReferencedBy>00-3880945351</normativelyReferencedBy>
<normativelyReferencedBy>BS EN 12899-1:2007</normativelyReferencedBy>
</relation>
<relation>
<normativelyReferencedBy>00-3880945351</normativelyReferencedBy>
<normativelyReferencedBy>BS EN 12899-1:2007</normativelyReferencedBy>
</relation>
<relation>
<normativelyReferencedBy>01-1012946847</normativelyReferencedBy>
<normativelyReferencedBy>BS EN 13291-2:2003</normativelyReferencedBy>
</relation>
</relations>

在这个xml中,前两个节点是相同的,文本也是相同的,所以我想将它们的文件名返回为: 我想通过marklogic服务器中的xquery返回。

Result:
abc.xml
<relation>
<normativelyReferencedBy>00-3880945351</normativelyReferencedBy>
<normativelyReferencedBy>BS EN 12899-1:2007</normativelyReferencedBy>
</relation>

2 个答案:

答案 0 :(得分:0)

通过使用一些XSLT你可以做这样的事情

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:template match="//relation[preceding-sibling::relation
        [./normativelyReferencedBy/text() = current()/normativelyReferencedBy/text()]]
        ">
        <xsl:copy>
            <xsl:copy-of select="./*"></xsl:copy-of>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="text()"></xsl:template>

</xsl:stylesheet>

它仅用作样板文件,但它返回在它们前面有重复的元素。您需要自己添加所需的信息。

答案 1 :(得分:0)

Erik的回答很好。但是,此解决方案将捕获重复元素并不总是先于彼此的情况:

xquery version "1.0-ml";

let $data :=     
<relations>
<relation>
<normativelyReferencedBy>00-3880945351</normativelyReferencedBy>
<normativelyReferencedBy>BS EN 12899-1:2007</normativelyReferencedBy>
</relation>
<relation>
<normativelyReferencedBy>00-3880945351</normativelyReferencedBy>
<normativelyReferencedBy>BS EN 12899-1:2007</normativelyReferencedBy>
</relation>
<relation>
<normativelyReferencedBy>01-1012946847</normativelyReferencedBy>
<normativelyReferencedBy>BS EN 13291-2:2003</normativelyReferencedBy>
</relation>
</relations>

let $map := map:map()

let $uniqueList :=
for $each at $i in $data/relation
 for $every at $j in $data/relation
   where $i ne $j
     return 
       if(fn:deep-equal($each, $every)) then
         if(fn:exists(map:get($map, xs:string($j)))) then () else map:put($map, xs:string($i), xs:string($j)) 
       else ()

return
<relations>
{
for $each at $i in $data/relation
  return 
   if(fn:exists(map:get($map, xs:string($i)))) then $each else ()
}
</relations>