开发者

XSLT: Remove duplicate nodes based on name attribute

I have the below input XML which needs to be transformed with an xslt

Input Xml:

<result>
    <circuit>MX123456</circuit>
    <psaresult>
        <Live_Alarms>
            <diagnosis>
                <utr>xxx</utr>
                <dtr>xxx</dtr>
                <text />
                <site>xxx</site>
                <address />
                <tech_type />
                <end />
                <network_type>xxx</network_type>
            </diagnosis>
            <Alarms>
                <alarmId>463</alarmId>
                <cct>xxx</cct>
                <eventTime>12/05/11 09:21:21</eventTime>
                <clearTime />
                <problemCode>xxxx</problemCode>
                <problemText>xxxx</problemText>开发者_运维知识库;
                <equipmentName>xxx</equipmentName>
                <unit>xxx</unit>
                <rcKey>xxx</rcKey>
                <category>xxx</category>
                <rootCause>xxxx</rootCause>
            </Alarms>
            <Alarms>
                <alarmId>464</alarmId>
                <cct>xxx</cct>
                <eventTime>12/05/11 09:21:22</eventTime>
                <clearTime />
                <problemCode>yyyy</problemCode>
                <problemText>yyyy</problemText>
                <equipmentName>yyyy</equipmentName>
                <unit>yyyy</unit>
                <rcKey>yyyy</rcKey>
                <category>yyyy</category>
                <rootCause>yyyy</rootCause>
            </Alarms>
        </Live_Alarms>
    </psaresult>
</result>

Expected output:

<result>
    <circuit>MX123456</circuit>
    <psaresult>
        <Live_Alarms>
            <psadiagnosis>
                <utr>xxx</utr>
                <dtr>xxx</dtr>
                <text />
                <site>xxx</site>
                <address />
                <tech_type />
                <end />
                <network_type>xxx</network_type>
            </psadiagnosis>
            <Alarms>
                <alarmId>463</alarmId>
                <cct>xxx</cct>
                <eventTime>12/05/11 09:21:21</eventTime>
                <clearTime />
                <problemCode>xxxx</problemCode>
                <problemText>xxxx</problemText>
                <equipmentName>xxx</equipmentName>
                <unit>xxx</unit>
                <rcKey>xxx</rcKey>
                <category>xxx</category>
                <rootCause>xxxx</rootCause>
            </Alarms>
        </Live_Alarms>
    </psaresult>
</result>

Note: Ony the first Alarms node is needed like what SelectSinglenode does and all others needed to be truncated from the output. Can you please advise how this can be achieved from an xslt?


Here is the canonical identity rule - based solution:

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

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

 <xsl:template match="Alarms[position() >1]"/>
</xsl:stylesheet>

When applied on the provided XML document:

<result>
    <circuit>MX123456</circuit>
    <psaresult>
        <Live_Alarms>
            <diagnosis>
                <utr>xxx</utr>
                <dtr>xxx</dtr>
                <text />
                <site>xxx</site>
                <address />
                <tech_type />
                <end />
                <network_type>xxx</network_type>
            </diagnosis>
            <Alarms>
                <alarmId>463</alarmId>
                <cct>xxx</cct>
                <eventTime>12/05/11 09:21:21</eventTime>
                <clearTime />
                <problemCode>xxxx</problemCode>
                <problemText>xxxx</problemText>
                <equipmentName>xxx</equipmentName>
                <unit>xxx</unit>
                <rcKey>xxx</rcKey>
                <category>xxx</category>
                <rootCause>xxxx</rootCause>
            </Alarms>
            <Alarms>
                <alarmId>464</alarmId>
                <cct>xxx</cct>
                <eventTime>12/05/11 09:21:22</eventTime>
                <clearTime />
                <problemCode>yyyy</problemCode>
                <problemText>yyyy</problemText>
                <equipmentName>yyyy</equipmentName>
                <unit>yyyy</unit>
                <rcKey>yyyy</rcKey>
                <category>yyyy</category>
                <rootCause>yyyy</rootCause>
            </Alarms>
        </Live_Alarms>
    </psaresult>
</result>

exactly the wanted, correct result is produced:

<result>
   <circuit>MX123456</circuit>
   <psaresult>
      <Live_Alarms>
         <diagnosis>
            <utr>xxx</utr>
            <dtr>xxx</dtr>
            <text/>
            <site>xxx</site>
            <address/>
            <tech_type/>
            <end/>
            <network_type>xxx</network_type>
         </diagnosis>
         <Alarms>
            <alarmId>463</alarmId>
            <cct>xxx</cct>
            <eventTime>12/05/11 09:21:21</eventTime>
            <clearTime/>
            <problemCode>xxxx</problemCode>
            <problemText>xxxx</problemText>
            <equipmentName>xxx</equipmentName>
            <unit>xxx</unit>
            <rcKey>xxx</rcKey>
            <category>xxx</category>
            <rootCause>xxxx</rootCause>
         </Alarms>
      </Live_Alarms>
   </psaresult>
</result>

Explanation:

  1. The identity rule (template) copies every node "as-is".

  2. There is a single template overriding the identity rule. It matches any Alarms element that isn't the first Alarms child of its parent. This template has no body -- effectively discarding any such matched element from being copied into the output.


Use this:

<?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()[not(self::Alarms)] | Alarms[1]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Output XML:

<?xml version="1.0" encoding="utf-8"?>
<result>
    <circuit>MX123456</circuit>
    <psaresult>
        <Live_Alarms>
            <diagnosis>
                <utr>xxx</utr>
                <dtr>xxx</dtr>
                <text />
                <site>xxx</site>
                <address />
                <tech_type />
                <end />
                <network_type>xxx</network_type>
            </diagnosis>
            <Alarms>
                <alarmId>463</alarmId>
                <cct>xxx</cct>
                <eventTime>12/05/11 09:21:21</eventTime>
                <clearTime />
                <problemCode>xxxx</problemCode>
                <problemText>xxxx</problemText>
                <equipmentName>xxx</equipmentName>
                <unit>xxx</unit>
                <rcKey>xxx</rcKey>
                <category>xxx</category>
                <rootCause>xxxx</rootCause>
            </Alarms>


        </Live_Alarms>
    </psaresult>

</result>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜