【问题标题】:grouping repeating xml data with xsl使用 xsl 对重复的 xml 数据进行分组
【发布时间】:2015-03-20 07:36:44
【问题描述】:

我有一个 XML 文件,我需要使用 XSL 对其进行转换,以便对具有相同属性值名称 (@name) 的标签进行分组。在下面的示例输入中,唯一重复的值是“objectClass”。我似乎找不到任何其他可以解决我遇到的问题的帖子。以下是我的输入、代码、当前输出和所需输出。 XSL 2.0 不适合我。

输入:

<top>
<MPTPartyUserInqMultiLDAPData>
    <DN>cn=BRK001,ou=USERS,ou=INTERNAL,o=UMB</DN>
    <attribute-value name="passwordUniqueRequired">TRUE</attribute-value>
    <attribute-value name="passwordRequired">TRUE</attribute-value>
    <attribute-value name="uid">BRK001</attribute-value>
    <attribute-value name="initials">R</attribute-value>
    <attribute-value name="cn">BRK001</attribute-value>
    <attribute-value name="umbGUID">I00000000001498</attribute-value>
    <attribute-value name="objectClass">inetOrgPerson</attribute-value>
    <attribute-value name="objectClass">umbPerson</attribute-value>
    <attribute-value name="objectClass">organizationalPerson</attribute-value>
    <attribute-value name="objectClass">Person</attribute-value>
    <attribute-value name="objectClass">ndsLoginProperties</attribute-value>
    <attribute-value name="objectClass">Top</attribute-value>
    <attribute-value name="umbCustomer">22586</attribute-value>
</MPTPartyUserInqMultiLDAPData>
<MPTPartyUserInqMultiLDAPData>
    <DN>cn=BRK001,ou=USERS,ou=INTERNAL,o=UMB</DN>
    <attribute-value name="passwordUniqueRequired">TRUE</attribute-value>
    <attribute-value name="passwordRequired">TRUE</attribute-value>
    <attribute-value name="uid">BRK001</attribute-value>
    <attribute-value name="initials">R</attribute-value>
    <attribute-value name="cn">BRK001</attribute-value>
    <attribute-value name="umbGUID">I00000000001498</attribute-value>
    <attribute-value name="objectClass">inetOrgPerson</attribute-value>
    <attribute-value name="objectClass">umbPerson</attribute-value>
    <attribute-value name="objectClass">organizationalPerson</attribute-value>
    <attribute-value name="objectClass">Person</attribute-value>
    <attribute-value name="objectClass">ndsLoginProperties</attribute-value>
    <attribute-value name="objectClass">Top</attribute-value>
    <attribute-value name="umbCustomer">22586</attribute-value>
</MPTPartyUserInqMultiLDAPData>
</top>

当前 XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>

<xsl:key name="test" match="attribute-value" use="@name"/>

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

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

<xsl:template match="//*[local-name()='MPTPartyUserInqMultiLDAPData']">
    <xsl:variable name="ldapFormatted">
    <MPTPartyUserInqMultiLDAPData>
            <entries>
                <xsl:for-each select="attribute-value[count(. | key('test', @name)[1]) = 1]">
                    <attributes>
                        <name>
                            <xsl:value-of select="@name"/>
                        </name>
                        <xsl:for-each select="key('test', @name)">
                            <value>
                                <xsl:value-of select="."/>
                            </value>
                        </xsl:for-each>
                    </attributes>
                </xsl:for-each>
            </entries>
        </MPTPartyUserInqMultiLDAPData>
    </xsl:variable>

    <xsl:copy-of select="$ldapFormatted"/>

</xsl:template>

电流输出:

<top>
<MPTPartyUserInqMultiLDAPData>
    <entries>
        <attributes>
            <name>passwordUniqueRequired</name>
            <value>TRUE</value>
            <value>TRUE</value>
        </attributes>
        <attributes>
            <name>passwordRequired</name>
            <value>TRUE</value>
            <value>TRUE</value>
        </attributes>
        <attributes>
            <name>uid</name>
            <value>BRK001</value>
            <value>BRK001</value>
        </attributes>
        <attributes>
            <name>initials</name>
            <value>R</value>
            <value>R</value>
        </attributes>
        <attributes>
            <name>cn</name>
            <value>BRK001</value>
            <value>BRK001</value>
        </attributes>
        <attributes>
            <name>umbGUID</name>
            <value>I00000000001498</value>
            <value>I00000000001498</value>
        </attributes>
        <attributes>
            <name>objectClass</name>
            <value>inetOrgPerson</value>
            <value>umbPerson</value>
            <value>organizationalPerson</value>
            <value>Person</value>
            <value>ndsLoginProperties</value>
            <value>Top</value>
            <value>inetOrgPerson</value>
            <value>umbPerson</value>
            <value>organizationalPerson</value>
            <value>Person</value>
            <value>ndsLoginProperties</value>
            <value>Top</value>
        </attributes>
        <attributes>
            <name>umbCustomer</name>
            <value>22586</value>
            <value>22586</value>
        </attributes>
    </entries>
</MPTPartyUserInqMultiLDAPData>
<MPTPartyUserInqMultiLDAPData>
    <entries/>
</MPTPartyUserInqMultiLDAPData>
</top>

期望的输出:

<top>
<MPTPartyUserInqMultiLDAPData>
    <entries>
        <attributes>
            <name>passwordUniqueRequired</name>
            <value>TRUE</value>
        </attributes>
        <attributes>
            <name>passwordRequired</name>
            <value>TRUE</value>
        </attributes>
        <attributes>
            <name>uid</name>
            <value>BRK001</value>
        </attributes>
        <attributes>
            <name>initials</name>
            <value>R</value>
        </attributes>
        <attributes>
            <name>cn</name>
            <value>BRK001</value>
        </attributes>
        <attributes>
            <name>umbGUID</name>
            <value>I00000000001498</value>
        </attributes>
        <attributes>
            <name>objectClass</name>
            <value>inetOrgPerson</value>
            <value>umbPerson</value>
            <value>organizationalPerson</value>
            <value>Person</value>
            <value>ndsLoginProperties</value>
            <value>Top</value>
        </attributes>
        <attributes>
            <name>umbCustomer</name>
            <value>22586</value>
        </attributes>
    </entries>
</MPTPartyUserInqMultiLDAPData>
<MPTPartyUserInqMultiLDAPData>
    <entries>
        <attributes>
            <name>passwordUniqueRequired</name>
            <value>TRUE</value>
        </attributes>
        <attributes>
            <name>passwordRequired</name>
            <value>TRUE</value>
        </attributes>
        <attributes>
            <name>uid</name>
            <value>BRK001</value>
        </attributes>
        <attributes>
            <name>initials</name>
            <value>R</value>
        </attributes>
        <attributes>
            <name>cn</name>
            <value>BRK001</value>
        </attributes>
        <attributes>
            <name>umbGUID</name>
            <value>I00000000001498</value>
        </attributes>
        <attributes>
            <name>objectClass</name>
            <value>inetOrgPerson</value>
            <value>umbPerson</value>
            <value>organizationalPerson</value>
            <value>Person</value>
            <value>ndsLoginProperties</value>
            <value>Top</value>
        </attributes>
        <attributes>
            <name>umbCustomer</name>
            <value>22586</value>
        </attributes>
    </entries>
</MPTPartyUserInqMultiLDAPData>
</top>

如果我只有一个 MPTPartyUserInqMultiLDAPData 分组,则标记会正确分组,但是当我有多个迭代时,我会这样做,它会将它们分组在一起,如上所示,这是我不想要的。我理解它为什么这样做,但不知道如何将分组保留在 MPTPartyUserInqMultiLDAPData 标记内。

【问题讨论】:

    标签: xml xslt-1.0 xslt-grouping


    【解决方案1】:

    认为你想做这样的事情:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:key name="attr" match="attribute-value" use="concat(@name, '|', generate-id(..))"/>
    
    <xsl:template match="/top">
        <xsl:copy>
            <xsl:apply-templates select="MPTPartyUserInqMultiLDAPData"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="MPTPartyUserInqMultiLDAPData">
        <xsl:copy>
            <entries>
                <xsl:for-each select="attribute-value[count(. | key('attr', concat(@name, '|', generate-id(..)))[1])=1]">
                    <attributes>
                        <name>
                            <xsl:value-of select="@name"/>
                        </name>
                        <xsl:for-each select="key('attr', concat(@name, '|', generate-id(..)))">
                            <value>
                                <xsl:value-of select="."/>
                            </value>
                        </xsl:for-each>
                    </attributes>
                </xsl:for-each>
            </entries>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 谢谢,迈克尔。初步测试表明它可以工作(xmlSpy)。完成后,我将添加我的“真实生活”测试结果(DataPower 服务)。
    • 再次感谢迈克尔。我不得不稍微调整一下,因为我的实际输入 XML 是一个 SOAP 消息,并且文件中还有其他数据需要包含在结果文件中。我能够迅速做出改变。我不得不说,一百年后我不会想出你发布的内容。考虑回答这个线程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-03
    • 1970-01-01
    相关资源
    最近更新 更多