簡體   English   中英

如何根據條件從XML刪除節點?

[英]How to remove nodes from XML based on conditions?

我需要根據條件從XML下面刪除重復的節點。 有人可以幫我修復我編寫的XSLT嗎? 或建議解決方法?

我的要求:如果滿足以下條件,請刪除整個節點。

  1. 如果員工編號重復
  2. 如果以上條件為“ true”,則保留“類型”中為“員工”的Worker節點。 具有相同員工ID的其他重復的“工人”節點條目將具有“類型”作為“或有”。

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。 但是,我需要的是僅當“雇員ID”在XML中具有重復條目時,才將具有“類型為或有”類型的節點刪除?

考慮使用密鑰通過其Employee_ID查找Worker元素

<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]"/>

或者也許是這樣(即檢查是否有另一個具有相同Employee_ID Worker

<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元素時,您才真正需要這樣做。

將另一個謂詞(此處: [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的功能。 此外,我刪除了不必要的名稱空間聲明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM