循环遍历xsl中的元素但不能以期望的方式显示它

时间:2011-05-02 11:36:33

标签: xslt

我正在尝试显示下面提到的xml的元素:

<root>
  <LogException>
     <exceptionNotificationGroup>Person</exceptionNotificationGroup>
     <exceptionType>Implimentation Test</exceptionType>
     <createdDatetime>2011-03-29</createdDatetime>
     <exceptionSource>INFINITY</exceptionSource>
     <exceptionSourceReferenceId>2345610</exceptionSourceReferenceId>
     <exceptionTarget>RMB</exceptionTarget>
     <sourceSystem>ODS</sourceSystem>
     <message>Mandatory Field Missing-Test</message>
  </LogException>
  <LogException>
     <exceptionNotificationGroup>Vinayak</exceptionNotificationGroup>
     <exceptionType>Implimentation Testing</exceptionType>
     <createdDatetime>2012-03-29</createdDatetime>
     <exceptionSource>INFINITY Check</exceptionSource>
     <exceptionSourceReferenceId>2345610</exceptionSourceReferenceId>
     <exceptionTarget>ORMB</exceptionTarget>
     <sourceSystem>ODS</sourceSystem>
     <message>Mandatory Field Missing-Test</message>
  </LogException>
</root>

采用以下格式:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:tem="http://tempuri.org/">
  <soapenv:Header/>
  <soapenv:Body>
  <tem:LogException>
     <tem:exceptionNotificationGroup>Person</tem:exceptionNotificationGroup>
     <tem:exceptionType>Implimentation Test</tem:exceptionType>
     <tem:createdDatetime>2011-03-29</tem:createdDatetime>
     <tem:exceptionSource>INFINITY</tem:exceptionSource>
     <tem:exceptionSourceReferenceId>2345610</tem:exceptionSourceReferenceId>
     <tem:exceptionTarget>RMB</tem:exceptionTarget>
     <tem:sourceSystem>ODS</tem:sourceSystem>
     <tem:message>Mandatory Field Missing-Test</tem:message>
      </tem:LogException>
     <tem:LogException>
      <tem:exceptionNotificationGroup>Vinayak</tem:exceptionNotificationGroup>
     <tem:exceptionType>Implimentation Testing</tem:exceptionType>
     <tem:createdDatetime>2012-03-29</tem:createdDatetime>
     <tem:exceptionSource>INFINITY Check</tem:exceptionSource>
     <tem:exceptionSourceReferenceId>2345610</tem:exceptionSourceReferenceId>
     <tem:exceptionTarget>ORMB</tem:exceptionTarget>
     <tem:sourceSystem>ODS</tem:sourceSystem>
     <tem:message>Mandatory Field Missing-Test</tem:message>
   </tem:LogException>
  </soapenv:Body>
</soapenv:Envelope>

通过使用xslt我尝试了很多使用不同类型的循环但是我得不到正确的结果。

这是我的xslt:

<?xml version="1.0" encoding="UTF-8" ?>

<!-- New document created with EditiX at Fri Apr 29 09:54:32 IST 2011 -->

<xsl:stylesheet version="2.0" exclude-result-prefixes="xs xdt err fn" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes" xmlns:err="http://www.w3.org/2005/xqt-errors" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:param name="ns-prefix" select="'soapenv'"/>
    <xsl:param name="ns-namespace" select="'http://schemas.xmlsoap.org/soap/envelope/'"/>
    <xsl:param name="ns-prefix2" select="'tem'"/>
    <xsl:param name="ns-namespace2" select="'http://tempuri.org/'"/>
    <xsl:template match="//LogException"><!-- create child element -->
        <xsl:variable name="checkCount">
            <xsl:value-of select="count(//LogException)"/>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="$checkCount&lt;2">
                <xsl:element name="{$ns-prefix2}:LogException" namespace="{$ns-namespace2}">
                    <xsl:for-each select="//LogException/*">
                        <xsl:variable name="elementname">
                            <xsl:value-of select="name()"/>
                        </xsl:variable>
                        <xsl:element name="{$ns-prefix2}:{$elementname}" namespace="{$ns-namespace2}">
                            <xsl:value-of select="."/>
                        </xsl:element>
                    </xsl:for-each>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise><!--xsl:for-each select="//LogException"-->
                <xsl:variable name="loop">
                    <xsl:value-of select="number($checkCount)-1"/>
                </xsl:variable>
                <xsl:text>-----Checking the value of the total no. of LogException node-------</xsl:text>
                <xsl:value-of select="$checkCount"/>
                <xsl:text>--------Value checked------</xsl:text>
                <xsl:call-template name="incrementValue">
                    <xsl:with-param name="value">
                        <xsl:value-of select="number($loop)"/>
                    </xsl:with-param>
                    <xsl:with-param name="limit" select="number($checkCount)"/>
                </xsl:call-template><!--xsl:if test="number($checkCount)&gt;0"--><!--/xsl:if--><!--/xsl:for-each-->
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="incrementValue">
        <xsl:param name="value"/>
        <xsl:param name="limit"/>

        <xsl:if test="number($value)&lt;number($limit)">
            <xsl:text>-----inside condition----------</xsl:text>
            <xsl:value-of select="position()"/>
            <xsl:element name="{$ns-prefix2}:LogException" namespace="{$ns-namespace2}">
                <xsl:for-each select="//LogException[position()]/*">
                    <xsl:variable name="elementname">
                        <xsl:value-of select="name()"/>
                    </xsl:variable>
                    <xsl:element name="{$ns-prefix2}:{$elementname}" namespace="{$ns-namespace2}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:for-each>
            </xsl:element>
            <xsl:call-template name="incrementValue">
                <xsl:with-param name="value" select="$value + 1"/>
                <xsl:with-param name="limit" select="$limit"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
    <xsl:template match="/">
        <xsl:element name="soapenv:Envelope" namespace="{$ns-namespace}">
            <xsl:copy-of select="document('')/*/namespace::*[name()='soapenv' or name()='tem']"/>

            <xsl:element name="{$ns-prefix}:Header" namespace="{$ns-namespace}"/>
            <xsl:element name="{$ns-prefix}:Body" namespace="{$ns-namespace}">
                <xsl:apply-templates select="//LogException"/>
            </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

我得到的结果如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
       -----Checking the value of the total no. of LogException node-------2--------Value checked-----------inside condition----------1
       <tem:LogException>
         <tem:exceptionNotificationGroup>Person</tem:exceptionNotificationGroup>
         <tem:exceptionType>Implimentation Test</tem:exceptionType>
         <tem:createdDatetime>2011-03-29</tem:createdDatetime>
         <tem:exceptionSource>INFINITY</tem:exceptionSource>
         <tem:exceptionSourceReferenceId>2345610</tem:exceptionSourceReferenceId>
         <tem:exceptionTarget>RMB</tem:exceptionTarget>
         <tem:sourceSystem>ODS</tem:sourceSystem>
         <tem:message>Mandatory Field Missing-Test</tem:message>
         <tem:exceptionNotificationGroup>Vinayak</tem:exceptionNotificationGroup>
         <tem:exceptionType>Implimentation Testing</tem:exceptionType>
         <tem:createdDatetime>2012-03-29</tem:createdDatetime>
         <tem:exceptionSource>INFINITY Check</tem:exceptionSource>
         <tem:exceptionSourceReferenceId>2345610</tem:exceptionSourceReferenceId>
         <tem:exceptionTarget>ORMB</tem:exceptionTarget>
         <tem:sourceSystem>ODS</tem:sourceSystem>
         <tem:message>Mandatory Field Missing-Test</tem:message>
       </tem:LogException>
       -----Checking the value of the total no. of LogException node-------2--------Value checked-----------inside condition----------2
       <tem:LogException>
         <tem:exceptionNotificationGroup>Person</tem:exceptionNotificationGroup>
         <tem:exceptionType>Implimentation Test</tem:exceptionType>
         <tem:createdDatetime>2011-03-29</tem:createdDatetime>
         <tem:exceptionSource>INFINITY</tem:exceptionSource>
         <tem:exceptionSourceReferenceId>2345610</tem:exceptionSourceReferenceId>
         <tem:exceptionTarget>RMB</tem:exceptionTarget>
         <tem:sourceSystem>ODS</tem:sourceSystem>
         <tem:message>Mandatory Field Missing-Test</tem:message>
         <tem:exceptionNotificationGroup>Vinayak</tem:exceptionNotificationGroup>
         <tem:exceptionType>Implimentation Testing</tem:exceptionType>
         <tem:createdDatetime>2012-03-29</tem:createdDatetime>
         <tem:exceptionSource>INFINITY Check</tem:exceptionSource>
         <tem:exceptionSourceReferenceId>2345610</tem:exceptionSourceReferenceId>
         <tem:exceptionTarget>ORMB</tem:exceptionTarget>
         <tem:sourceSystem>ODS</tem:sourceSystem>
         <tem:message>Mandatory Field Missing-Test</tem:message>
      </tem:LogException>
   </soapenv:Body>
</soapenv:Envelope>

是否有人对这个问题有所了解?

2 个答案:

答案 0 :(得分:1)

这个XSLT 1.0样式表:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 exclude-result-prefixes="msxsl">
    <xsl:param name="pNamespaceURI" select="'http://tempuri.org/'"/>
    <xsl:param name="pPrefix" select="'tem'"/>
    <xsl:variable name="vDummyRTF">
        <xsl:element name="{$pPrefix}:dummy" namespace="{$pNamespaceURI}"/>
    </xsl:variable>
    <xsl:variable name="vNamespaceNode"
     select="msxsl:node-set($vDummyRTF)/*/namespace::*[name()=$pPrefix]"/>
    <xsl:template match="root">
        <soapenv:Envelope>
            <xsl:copy-of select="$vNamespaceNode"/>
            <soapenv:Header>
                <xsl:copy-of select="$vNamespaceNode"/>
            </soapenv:Header>
            <soapenv:Body>
                <xsl:copy-of select="$vNamespaceNode"/>
                <xsl:apply-templates/>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="{$pPrefix}:{name()}" namespace="{$pNamespaceURI}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

这个XSLT 2.0样式表:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <xsl:param name="pNamespaceURI" select="'http://tempuri.org/'"/>
    <xsl:param name="pPrefix" select="'tem'"/>
    <xsl:variable name="vNamespaceNode" as="node()">
        <xsl:namespace name="{$pPrefix}">
            <xsl:value-of select="$pNamespaceURI"/>
        </xsl:namespace>
    </xsl:variable>
    <xsl:template match="root">
        <soapenv:Envelope>
            <xsl:copy-of select="$vNamespaceNode"/>
            <soapenv:Header>
                <xsl:copy-of select="$vNamespaceNode"/>
            </soapenv:Header>
            <soapenv:Body>
                <xsl:copy-of select="$vNamespaceNode"/>
                <xsl:apply-templates/>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="{$pPrefix}:{name()}" namespace="{$pNamespaceURI}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

输出:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
    <soapenv:Header />
    <soapenv:Body>
        <tem:LogException>
            <tem:exceptionNotificationGroup>Person</tem:exceptionNotificationGroup>
            <tem:exceptionType>Implimentation Test</tem:exceptionType>
            <tem:createdDatetime>2011-03-29</tem:createdDatetime>
            <tem:exceptionSource>INFINITY</tem:exceptionSource>
            <tem:exceptionSourceReferenceId>2345610</tem:exceptionSourceReferenceId>
            <tem:exceptionTarget>RMB</tem:exceptionTarget>
            <tem:sourceSystem>ODS</tem:sourceSystem>
            <tem:message>Mandatory Field Missing-Test</tem:message>
        </tem:LogException>
        <tem:LogException>
            <tem:exceptionNotificationGroup>Vinayak</tem:exceptionNotificationGroup>
            <tem:exceptionType>Implimentation Testing</tem:exceptionType>
            <tem:createdDatetime>2012-03-29</tem:createdDatetime>
            <tem:exceptionSource>INFINITY Check</tem:exceptionSource>
            <tem:exceptionSourceReferenceId>2345610</tem:exceptionSourceReferenceId>
            <tem:exceptionTarget>ORMB</tem:exceptionTarget>
            <tem:sourceSystem>ODS</tem:sourceSystem>
            <tem:message>Mandatory Field Missing-Test</tem:message>
        </tem:LogException>
    </soapenv:Body>
</soapenv:Envelope>

答案 1 :(得分:0)

假设你只想深入两个级别,你可以试试这个:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="/root">
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
            <soapenv:Header/>
            <soapenv:Body>
                <xsl:apply-templates select="*"/>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>

    <xsl:template match="root/*">
        <xsl:element name="tem:{name()}">
            <xsl:apply-templates select="*"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="root/*/*">
        <xsl:element name="tem:{name()}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

通常,XSLT中的最佳做法是尽可能避免使用<xsl:for-each>标记。您可以使用<xsl:apply-templates>

定义更具体的模板