XSLT:根据name属性删除重复的节点

时间:2011-07-18 14:03:26

标签: xml xslt xpath

我有以下输入XML,需要使用xslt

进行转换

输入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>

预期产出:

<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>

注意:Ony需要第一个Alarms节点,就像SelectSinglenode所做的那样,所有其他节点都需要从输出中截断。你能告诉我们如何用xslt实现这个目标吗?

2 个答案:

答案 0 :(得分:2)

以下是基于规范身份规则的解决方案

<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>

应用于提供的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>

产生了正确的,正确的结果

<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>

<强>解释

  1. identity rule (模板)按“原样”复制每个节点。

  2. 有一个模板会覆盖身份规则。它匹配任何不是其父级的第一个Alarms子级的Alarms元素。此模板没有正文 - 有效地丢弃任何此类匹配元素被复制到输出中。

答案 1 :(得分:0)

使用此:

<?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>

输出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>