首页 文章

XSLT按元素名称分组

提问于
浏览
0

我是XSLt的新手 . 我需要在配置文件中查找输入XML中的元素,并根据它生成输出 . 查找值可以在名称中带有'Exception'的任何子elemnet中 . 以下是输入 Input XML 的示例

<output>
    <groups>
    <Exception_laptop>
            <Exception_laptop_code>100</Exception_laptop_code>
            <Exception_laptop_string>1414</Exception_laptop_string>
</Exception_laptop>
    <Exception_laptop>
            <Exception_laptop_code>-1210</Exception_laptop_code>
            <Exception_laptop_string>126</Exception_laptop_string>
    </Exception_laptop>
    <Exception_computer>
            <Exception_computer_code>111</Exception_computer_code>
            <Exception_computer_string>163</Exception_computer_string>
        </Exception_computer>
        <Exception_computer>
            <Exception_computer_code>100</Exception_computer_code>
            <Exception_computer_string>1414</Exception_computer_string>
        </Exception_computer>
        <UnitId>134</UnitId>
        <origin>1.0</origin>
    </groups>
</output>

输出应该是这样的

Intended output

<ResponseMessages>
<OutGroupMessages>
    <ExceptionGroup>Exception_laptop</ExceptionGroup>
    <ExceptionMessages>
        <Message>
            <Identifier>11</Identifier>
            <Message>message1</Message>
        </Message>
        <Message>
            <Identifier>12</Identifier>
            <Message>message2</Message>
        </Message>
    </ExceptionMessages>
</OutGroupMessages>
<OutGroupMessages>
<ExceptionGroup>Exception_computer</ExceptionGroup>
    <ExceptionMessages>
        <Message>
            <Identifier>15</Identifier>
            <Message>message4</Message>
        </Message>
        <Message>
            <Identifier>11</Identifier>
            <Message>message1</Message>
        </Message>
    </ExceptionMessages>
</OutGroupMessages>

我使用下面的xslt,但我对如何将'OutGroupMessages'父级添加到每个异常组有点迷失 .

XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xalan="http://xml.apache.org/xslt" xmlns:str="http://exslt.org/strings"
    xmlns:set="http://exslt.org/sets" xmlns:math="http://exslt.org/math"
    xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:regexp="http://exslt.org/regular-expressions"
    xmlns:dyn="http://exslt.org/dynamic" xmlns:dp="http://www.datapower.com/extensions"
    xmlns:exsl="http://exslt.org/common" xmlns:date="http://exslt.org/dates-and-times"
    xmlns:io="http://www.w3.org/2003/05/soap-envelope" xmlns:io3="http://www.ibm.com/xmlns/prod/websphere/mq/sca/6.0.0"
    xmlns:io2="http://www.ibm.com/websphere/sibx/smo/v6.0.1" xmlns:io4="http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:io5="http://www.ibm.com/xmlns/prod/websphere/http/sca/6.1.0"
    xmlns:xs4xs="http://www.w3.org/2001/XMLSchema" xmlns:io6="http://www.w3.org/2005/08/addressing"
    version="1.0">

        <xsl:template name="mapExceptions">
            <xsl:param name="exceptions"/>
            <ResponseMessages>
                <xsl:if test="boolean(//*[contains(local-name(.),'Exception')])">
                <OutGroupMessages>
                    <xsl:apply-templates mode="Exception" select="$exceptions/output/groups/*"/>
                    </OutGroupMessages>
                </xsl:if>
            </ResponseMessages>
        </xsl:template>


        <xsl:template match="//*[contains(local-name(),'Exception')]" mode="Exception">

                <xsl:if test="local-name(preceding-sibling::*[1]) != local-name(.)">
                    <xsl:element name="ExceptionGroup">
                        <xsl:value-of select="local-name(.)"/>
                    </xsl:element>
                </xsl:if>
                <ExceptionMessages>
                    <xsl:call-template name="mapError">
                        <xsl:with-param name="errorcode">
                            <xsl:value-of select="./*[contains(local-name(.),'_code')]"/>
                        </xsl:with-param>
                        <xsl:with-param name="errorString">
                            <xsl:value-of select="./*[contains(local-name(.),'_string')]"/>
                        </xsl:with-param>
                    </xsl:call-template>
                </ExceptionMessages>

        </xsl:template>

        <xsl:template name="mapError">
            <xsl:param name="errorcode"/>
            <xsl:param name="errorstring"/>
            <xsl:variable name="config" select="'ErrorMapperConfig.xml'"/>
            <xsl:variable name="errorconfig" select="document($config)"/>
            <xsl:for-each select="$errorconfig/ErrorConfig/Error">
                <xsl:if test="ErrorCode = $errorcode and ErrorString= $errorstring">
                    <Message>
                        <xsl:element name="Identifier">
                            <xsl:value-of select="Identifier"/>
                        </xsl:element>
                        <xsl:element name="Message">
                            <xsl:value-of select="/Message"/>
                        </xsl:element>
                    </Message>
                </xsl:if>
            </xsl:for-each>
        </xsl:template>

    </xsl:stylesheet>

Output I am getting

<ResponseMessages>
    <OutGroupMessages>
        <ExceptionGroup>Exception_laptop</ExceptionGroup>
        <ExceptionMessages>
            <Message>
                <Identifier>11</Identifier>
                <Message>message1</Message>
            </Message>
        </ExceptionMessages>
        <ExceptionMessages>
            <Message>
                <Identifier>12</Identifier>
                <Message>message2</Message>
            </Message>
        </ExceptionMessages>
        <ExceptionGroup>Exception_computer</ExceptionGroup>
        <ExceptionMessages>
            <Message>
                <Identifier>15</Identifier>
                <Message>message4</Message>
            </Message>
        </ExceptionMessages>
        <ExceptionMessages>
            <Message>
                <Identifier>11</Identifier>
                <Message>message1</Message>
            </Message>
        </ExceptionMessages>
    </OutGroupMessages>
</ResponseMessages>

提前致谢

1 回答

  • 1

    如果您使用的是XSLT 1.0,则应该学习如何使用Muenchian grouping . 在您的情况下,这看起来像:

    XSLT 1.

    <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="elem-by-name" match="groups/*" use="name()" />
    
    <xsl:template match="/output">
        <ResponseMessages>
            <!-- for each distinct exception group -->
            <xsl:for-each select="groups/*[starts-with(name(), 'Exception_')][count(. | key('elem-by-name', name())[1]) = 1]">
                <OutGroupMessages>
                    <ExceptionGroup>
                        <xsl:value-of select="name()"/>
                    </ExceptionGroup>
                    <!-- for each member of current group -->
                    <xsl:for-each select="key('elem-by-name', name())">
                        <Message>
                            <Identifier>
                                <xsl:value-of select="*[contains(name(), '_code')]"/>
                            </Identifier>
                            <Message>
                                <xsl:value-of select="*[contains(name(), '_string')]"/>
                            </Message>
                        </Message>
                    </xsl:for-each>
                </OutGroupMessages>
            </xsl:for-each>
        </ResponseMessages>
    </xsl:template>
    
    </xsl:stylesheet>
    

    应用于您的输入示例,结果将是:

    <?xml version="1.0" encoding="UTF-8"?>
    <ResponseMessages>
       <OutGroupMessages>
          <ExceptionGroup>Exception_laptop</ExceptionGroup>
          <Message>
             <Identifier>100</Identifier>
             <Message>1414</Message>
          </Message>
          <Message>
             <Identifier>-1210</Identifier>
             <Message>126</Message>
          </Message>
       </OutGroupMessages>
       <OutGroupMessages>
          <ExceptionGroup>Exception_computer</ExceptionGroup>
          <Message>
             <Identifier>111</Identifier>
             <Message>163</Message>
          </Message>
          <Message>
             <Identifier>100</Identifier>
             <Message>1414</Message>
          </Message>
       </OutGroupMessages>
    </ResponseMessages>
    

    我不确定预期输出中的值来自何处:在输入中找不到它们,而不是在样式表中 .

相关问题