XSLT: удалить дубликаты узлов на основе атрибута имени - PullRequest
4 голосов
/ 18 июля 2011

У меня есть приведенный ниже входной 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>

Примечание : нужен только первый узел Alarms, как то, что делает SelectSinglenode, а все остальные необходимо обрезать из выходных данных.Подскажите, пожалуйста, как этого можно добиться с помощью xslt?

Ответы [ 2 ]

2 голосов
/ 19 июля 2011

Вот решение на основе правил канонической идентификации :

<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. Правило идентификации (шаблон) копирует каждый узел "как есть".

  2. Существует один шаблон, переопределяющий правило идентификации . Он соответствует любому элементу Alarms, который не является первым Alarms дочерним элементом его родителя. Этот шаблон не имеет тела - фактически отбрасывает любой подобный соответствующий элемент от копирования в вывод.

0 голосов
/ 18 июля 2011

Используйте это:

<?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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...