如何使用XSL在XML中找到所有唯一的Node?

时间:2015-09-04 12:27:26

标签: xml xslt xslt-1.0

嗨,我是xslt转换的新手。我需要从输入xml中找到所有唯一节点(需要丢弃节点内所有字段与其他节点相同的节点)

我的输入xml是

<ns7:newElement xmlns:ns7="http://TargetNamespace.com/NewElement">
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>56201</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>22</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC>
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>7643</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>20</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC>
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>56201</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>22</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC></ns7:newElement>

我希望输出中的唯一节点为

<ns7:newElement xmlns:ns7="http://TargetNamespace.com/NewElement">
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>56201</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>22</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC>
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>7643</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>20</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC></ns7:newElement>

如何使用xslt 1.0实现这一目标。我不能使用xslt 2.0。

3 个答案:

答案 0 :(得分:0)

functx:distinct-deep函数根据节点是否深度相等来比较节点,然后仅返回具有每个不同值的第一个节点。您可以使用下面的代码。

<activity android:name=".activity.FirstLoginActivity">
    <intent-filter>
        <data android:scheme="https"
              android:host="app.inetrack.com"
              android:pathPrefix="/#home"/>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

refer this

答案 1 :(得分:0)

假设您使用正确的输入修复了问题,以下几行中的内容将起作用。您需要将其扩展到您认为“字段”的任何内容。

<xsl:stylesheet
    xmlns:e="http://TargetNamespace.com/NewElement"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <!-- your current code here, the part you didn't show, so you'll need 
         to adjust the rest to match whatever structure you already have -->

    <xsl:key match="e:LFULL-REC" name="dupe" use="concat(e:MESSAGE-GROUP-ID, '-', e:FULL-TOTAL-MESSAGE-CNT)" />

    <xsl:template match="e:LFULL-REC[generate-id(.) = generate-id(key('dupe', concat(e:MESSAGE-GROUP-ID, '-', e:FULL-TOTAL-MESSAGE-CNT)))]">
        <xsl:copy>
            <xsl:apply-templates select="node() |@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="e:LFULL-REC" />
</xsl:stylesheet>

这使用Muenchian Grouping,以第一个提出这个想法的人命名。谷歌它,有很多教程,甚至是Wikipedia article on the subject

答案 2 :(得分:0)

最后我能够成功转换它

我的输入xml是

    <ns7:newElement xmlns:ns7="http://TargetNamespace.com/NewElement">
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>56201</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>22</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC>
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>7643</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>20</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC>
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>56201</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>22</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC></ns7:newElement>

我更新的xslt是

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:ns7="http://TargetNamespace.com/NewElement">

    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:key match="ns7:LFULL-REC" name="dupe" use="concat(ns7:MESSAGE-GROUP-ID, '-', ns7:FULL-TOTAL-MESSAGE-CNT,'-',ns7:FULL-MESSAGE-SERIAL-NO,'-',ns7:FULL-TRANSMITED-REC-CNT)" />

    <xsl:template match="/">
        <ns7:newElement>
            <xsl:for-each select="ns7:newElement/ns7:LFULL-REC[generate-id(.) = generate-id(key('dupe', concat(ns7:MESSAGE-GROUP-ID, '-', ns7:FULL-TOTAL-MESSAGE-CNT,'-',ns7:FULL-MESSAGE-SERIAL-NO,'-',ns7:FULL-TRANSMITED-REC-CNT)))]">
                <xsl:copy-of select="."/> 
            </xsl:for-each>
        </ns7:newElement>
    </xsl:template>

</xsl:stylesheet>

我的输出xml是

    <ns7:newElement xmlns:ns7="http://TargetNamespace.com/NewElement">
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>56201</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>22</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC>
<ns7:LFULL-REC>
    <ns7:MESSAGE-GROUP-ID>7643</ns7:MESSAGE-GROUP-ID>
    <ns7:FULL-TOTAL-MESSAGE-CNT>20</ns7:FULL-TOTAL-MESSAGE-CNT>
    <ns7:FULL-MESSAGE-SERIAL-NO>1</ns7:FULL-MESSAGE-SERIAL-NO>
    <ns7:FULL-TRANSMITED-REC-CNT>42</ns7:FULL-TRANSMITED-REC-CNT>
</ns7:LFULL-REC></ns7:newElement>

感谢@Abel提供有价值的输入