我需要根据条件从下面的XML中删除重复的节点。有人可以帮我修一下我写的XSLT吗?或建议一个解决方法?
我的要求:如果满足以下条件,则删除整个节点。
XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<Workers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<File>22.0</File>
<Date>2014-05-31T16:20:07.000-07:00</Date>
<Worker_Count>2</Worker_Count>
</Header>
<Worker>
<Summary>
<Employee_ID>12345800</Employee_ID>
<Name>John Davis (12345800)</Name>
<Type>Employee</Type>
</Summary>
</Worker>
<Worker>
<Summary>
<Employee_ID>12345800</Employee_ID>
<Name>John Davis (12345800)</Name>
<Type>Contingent</Type>
</Summary>
</Worker>
<Worker>
<Summary>
<Employee_ID>32451854</Employee_ID>
<Name>Felix (32451854)</Name>
<Type>Employee</Type>
</Summary>
</Worker>
<Worker>
<Summary>
<Employee_ID>23471732</Employee_ID>
<Name>David (23471732)</Name>
<Type>Contingent</Type>
</Summary>
</Worker>
<Worker>
<Summary>
<Employee_ID>38741297</Employee_ID>
<Name>Sam Daniel (38741297)</Name>
<Type>Employee</Type>
</Summary>
</Worker>
<Worker>
<Summary>
<Employee_ID>38741297</Employee_ID>
<Name>Sam Daniel (38741297)</Name>
<Type>Contingent</Type>
</Summary>
</Worker>
</Workers>
上面的XML需要转换如下。
<?xml version="1.0" encoding="UTF-8"?>
<Workers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<File>22.0</File>
<Date>2014-05-31T16:20:07.000-07:00</Date>
<Worker_Count>2</Worker_Count>
</Header>
<Worker>
<Summary>
<Employee_ID>12345800</Employee_ID>
<Name>John Davis (12345800)</Name>
<Type>Employee</Type>
</Summary>
</Worker>
<Worker>
<Summary>
<Employee_ID>32451854</Employee_ID>
<Name>Felix (32451854)</Name>
<Type>Employee</Type>
</Summary>
</Worker>
<Worker>
<Summary>
<Employee_ID>23471732</Employee_ID>
<Name>David (23471732)</Name>
<Type>Contingent</Type>
</Summary>
</Worker>
<Worker>
<Summary>
<Employee_ID>38741297</Employee_ID>
<Name>Sam Daniel (38741297)</Name>
<Type>Employee</Type>
</Summary>
</Worker>
</Workers>
我在XSLT下面写过。不确定如何在XSLT下面添加条件以删除包含重复员工ID的节点,其中类型为'Contingent'
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ws="urn:com.workday/workersync">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Workers/Worker[Summary/Type='Contingent']"/>
</xsl:stylesheet>
在XSLT之上删除所有值为'Contingent'的Type。但是,我需要的是只有当'Employee id'在XML中有重复的条目时才删除具有Type为Contingent的节点?
答案 0 :(得分:3)
考虑使用密钥按Worker
Employee_ID
个元素
<xsl:key name="Worker" match="Worker" use="Summary/Employee_ID" />
这意味着您可以编写模板匹配以删除Worker
元素,如下所示:
<xsl:template match="Worker[Summary/Type='Contingent'][count(key('Worker', Summary/Employee_ID)) > 1]"/>
或者可能是这样(即检查第二个Worker
具有相同的Employee_ID
<xsl:template match="Worker[Summary/Type='Contingent'][key('Worker', Summary/Employee_ID)[2]]"/>
试试这个XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ws="urn:com.workday/workersync">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="Worker" match="Worker" use="Summary/Employee_ID" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Worker[Summary/Type='Contingent'][key('Worker', Summary/Employee_ID)[2]]"/>
</xsl:stylesheet>
注意,无需在完整的/Workers/Worker
路径上进行匹配。如果XML中的不同级别有Worker
个元素,那么在这种情况下你真的只需要这样做。
答案 1 :(得分:1)
将另一个谓词(此处为:[Summary/Employee_ID = preceding-sibling::Worker/Summary/Employee_ID or Summary/Employee_ID = following-sibling::Worker/Summary/Employee_ID]
)添加到虚拟模板的匹配表达式中。
以下模板生成所需的输出:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Workers/Worker[Summary/Type='Contingent'][Summary/Employee_ID = preceding-sibling::Worker/Summary/Employee_ID or Summary/Employee_ID = following-sibling::Worker/Summary/Employee_ID]"/>
</xsl:stylesheet>
如果谓词是以这种方式链接的,那么所有必须满足匹配,就像在逻辑AND中一样。
除了添加额外的谓词之外,我还将XSLT版本更改为1.0,因为模板不使用版本2.0功能。另外,我删除了不必要的名称空间声明。