问题描述
如果输入 xml 中出现具有重复 Emplid 的记录,那么我想删除 状态 为“已撤消”的记录。如果具有相同 emplid 的记录出现两次,我只想保留状态为活动的记录。
输入xml
<Recordset>
<Record>
<Emplid>10001</Emplid>
<name>Bob Dylan</name>
<country>USA</country>
<company>Columbia</company>
<status>active</status>
<year>1985</year>
</Record>
<Record>
<Emplid>10002</Emplid>
<name>Bonnie Tyler</name>
<country>UK</country>
<company>CBS Records</company>
<status>withdrawn</status>
<year>1988</year>
</Record>
<Record>
<Emplid>10001</Emplid>
<name>Bob Dylan</name>
<country>Uk</country>
<company>CBS Records</company>
<status>withdrwan</status>
<year>1975</year>
</Record>
</Recordset>
预期的 xml
Recordset>
<Record>
<Emplid>10001</Emplid>
<name>Bob Dylan</name>
<country>USA</country>
<company>Columbia</company>
<status>active</status>
<year>1985</year>
</Record>
<Record>
<Emplid>10002</Emplid>
<name>Bonnie Tyler</name>
<country>UK</country>
<company>CBS Records</company>
<status>withdrawn</status>
<year>1988</year>
</Record>
</Recordset>
感谢有人能帮助我。
解决方法
您可以尝试以下 XSLT。
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Record[status='withdrawn']">
<xsl:variable name="Emplid" select="./Emplid"/>
<xsl:choose>
<xsl:when test="count(/Recordset/Record[Emplid=$Emplid]) > 1">
</xsl:when>
<xsl:when test="count(/Recordset/Record[Emplid=$Emplid]) = 1">
<xsl:copy-of select="."/>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
,
所以基本上你想复制所有活动记录,以及任何没有活动记录的撤回记录和相同的 Emplid?
没错
好吧,那为什么不这样做呢:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="act" match="Record[status='active']" use="Emplid" />
<xsl:template match="/Recordset">
<xsl:copy>
<xsl:copy-of select="Record[status='active']"/>
<xsl:copy-of select="Record[status='withdrawn'][not(key('act',Emplid))]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果你想保持原来的顺序,可以将两个xsl:copy-of
指令合二为一:
<xsl:copy-of select="Record[status='active'] | Record[status='withdrawn'][not(key('act',Emplid))]"/>
注意使用 key 来解决交叉引用。