使用多个记录(xslt 2或3)删除重复的节点XML



我有一个XML,里面有数百条这种格式的记录(这里只显示了2条)

<assessment> 
<subject>
<Name>470  470 015</Name>
<LAD>3.446887644423149</LAD>
<LAD>3.446887644423149</LAD>
<LM>4.049357373198344</LM>
<LM>4.049357373198344</LM>
<RCA>3.283339910532276</RCA>
<RCA>3.283339910532276</RCA>
</subject>
<subject>
<Name>230 230067</Name>
<LAD>2.392278459908628</LAD>
<LAD>2.392278459908628</LAD>
<LM>3.50258194988953</LM>
<LM>3.50258194988953</LM>
<RCA>3.274917502338067</RCA>
<RCA>3.274917502338067</RCA>
</subject>
</assessment>

我想删除重复的节点,使其看起来像这个

<assessment> 
<subject>
<Name>470  470 015</Name>
<LAD>3.446887644423149</LAD>
<LM>4.049357373198344</LM>
<RCA>3.283339910532276</RCA>
</subject>
<subject>
<Name>230 230067</Name>
<LAD>2.392278459908628</LAD>
<LM>3.50258194988953</LM>
<RCA>3.274917502338067</RCA>
</subject>
</assessment>

基于前面对类似问题的回答中的代码(https://stackoverflow.com/a/37078109/18941723),我能够处理第一条记录,但不能处理文件中的所有记录。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="*" group-by="name()">
<xsl:apply-templates select="current-group()[1]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

尝试更改:

match="/*"

至:

match="subject"

Martin评论道:

根据元素/节点名称,当前答案和您的尝试标识重复。我想知道你是否可以在一个subject元素中有几个同名的元素(例如LAD),它们可以有不同的值,在这种情况下你需要做什么。

一个选项是通过指定composite="yes"并将.normalize-space()添加到group-by来使用复合密钥。这将保留每个元素名称/值组合的一个实例。

示例。。。

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" expand-text="yes">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="subject">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="*" group-by="name(),normalize-space()" composite="yes">
<xsl:apply-templates select="current-group()[1]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

你有正确的方法,下面是我的做法:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="subject">
<xsl:copy>
<xsl:for-each-group select="*" group-by="name()">
<xsl:copy-of select="current-group()[1]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

请在此处查看它的工作情况:https://xsltfiddle.liberty-development.net/6qjt5SC

相关内容

  • 没有找到相关文章