This discussion is archived
3 Replies Latest reply: Oct 18, 2013 5:15 AM by tsuji RSS

Need to exclude the empty elements after mapping in xslt.

987727 Newbie
Currently Being Moderated

Hi Team,

 

I have a requirement. I need to invoke a wsdl which will have some po details. I'm using transformation to map the value from my local bpel variable to invoke variable. It is mostly a one-one mapping. no functions no looping and no complex transformation. Now the requirement is that I need to only send the elements which has the value also to add, there is no particular element which can be empty. There can be three elements empty or four or any. I need to map all and then I need to send only the elements those has values. Below is my mapping.

 

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

<?oracle-xsl-mapper <!-- SPECIFICATION OF MAP SOURCES AND TARGETS, DO NOT MODIFY. -->

  <mapSources>

    <source type="XSD">

      <schema location="POTest.xsd"/>

      <rootElement name="POTestProcessResponse" namespace="http://xmlns.oracle.com/POTest"/>

    </source>

  </mapSources>

  <mapTargets>

    <target type="XSD">

      <schema location="POTest.xsd"/>

      <rootElement name="POTestProcessResponse" namespace="http://xmlns.oracle.com/POTest"/>

    </target>

  </mapTargets>

  <!-- GENERATED BY ORACLE XSL MAPPER 10.1.3.3.0(build 070615.0525) AT [THU OCT 17 10:53:26 GMT 2013]. -->

?>

<xsl:stylesheet version="1.0"

                xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions"

                xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"

                xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"

                xmlns:ns1="http://xmlns.oracle.com/POTest"

                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

                xmlns:ora="http://schemas.oracle.com/xpath/extension"

                xmlns:ehdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.esb.server.headers.ESBHeaderFunctions"

                xmlns:ns0="http://www.w3.org/2001/XMLSchema"

                xmlns:orcl="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"

                xmlns:ids="http://xmlns.oracle.com/bpel/services/IdentityService/xpath"

                xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath"

                exclude-result-prefixes="xsl ns1 ns0 xref xp20 bpws ora ehdr orcl ids hwf">

 

  <xsl:template match="/">

    <ns1:POTestProcessResponse>

      <xsl:attribute name="OrderDate">

        <xsl:value-of select="/ns1:POTestProcessResponse/@OrderDate"/>

      </xsl:attribute>

      <ns1:name>

        <xsl:value-of select="/ns1:POTestProcessResponse/ns1:name"/>

      </ns1:name>

      <ns1:street>

        <xsl:value-of select="/ns1:POTestProcessResponse/ns1:street"/>

      </ns1:street>

      <ns1:city>

        <xsl:value-of select="/ns1:POTestProcessResponse/ns1:city"/>

      </ns1:city>

      <ns1:state>

        <xsl:value-of select="/ns1:POTestProcessResponse/ns1:state"/>

      </ns1:state>

      <ns1:zip>

        <xsl:value-of select="/ns1:POTestProcessResponse/ns1:zip"/>

      </ns1:zip>

    </ns1:POTestProcessResponse>

  </xsl:template>

 

  </xsl:stylesheet>

------------------------------------------------------------------------------------------------------------------------

Here I just mentioned only some elements but there are lot of other elements which can also be empty. If I keep on putting an if condition for each and every element it will messup the code. which I don't want to do due to lot of elements that needs to be checked. I tried with following templates.

 

1)

<xsl:template match="*[not(child::node())]"/>

  <xsl:template match="@*|node()">

<xsl:if test=". != '' or ./@* != ''">

   <xsl:copy>

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

   </xsl:copy>

</xsl:if>

</xsl:template>

 

2)

<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="*[not(node())]

  |

   *[not(node()[2])

   and

     node()/self::text()

   and

     not(normalize-space())

     ]

  "/>

 

3)

<xsl:template match="/">

    <xsl:apply-templates select="*"/>

  </xsl:template>

  <xsl:template match="*">

    <xsl:if test=". != ''">

      <xsl:copy>

        <xsl:element name="name()">

          <xsl:copy-of select="@*"/>

          <xsl:apply-templates/>

        </xsl:element>

      </xsl:copy>

    </xsl:if>

  </xsl:template>

 

 

But none of them is working. Kindly help. It is the only issue which is blocking.

 

 

Help is greatly appreciated.

 

 

Regards,

Venkatesh.

  • 1. Re: Need to exclude the empty elements after mapping in xslt.
    tsuji Journeyer
    Currently Being Moderated

    Does this set of templates suit you?

     

    <xsl:strip-space elements="*" />

    <xsl:template match="*">

    <xsl:if test=".!='' or count(@*)!=0">

      <xsl:copy>

       <xsl:apply-templates select="*|@*|text()" />

      </xsl:copy>

    </xsl:if>

    </xsl:template>

    <xsl:template match="@*">

    <xsl:copy-of select="." />

    </xsl:template>

    <xsl:template match="text()">

    <xsl:value-of select="." />

    </xsl:template>

     

    ps There is some artifact in the rendering like an envelop in front of * in the select attribute. Just ignore it. (Eventually I don't understand how these forums work anymore...)

  • 2. Re: Need to exclude the empty elements after mapping in xslt.
    987727 Newbie
    Currently Being Moderated

    I received the following errors:

     

      Line Number:(55) : Error: "xsl:strip-space" XSL Element Currently not Supported

      Line Number:(31) : Error: <xsl:template match="/"> and <xsl:template name="..."> are the only permitted <template> elements in the XSL

      Line Number:(53) : Error: <xsl:template match="/"> and <xsl:template name="..."> are the only permitted <template> elements in the XSL

      Line Number:(56) : Error: <xsl:template match="/"> and <xsl:template name="..."> are the only permitted <template> elements in the XSL

     

     

    Below is the complete transformation code.:

     

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

    <?oracle-xsl-mapper

      <!-- SPECIFICATION OF MAP SOURCES AND TARGETS, DO NOT MODIFY. -->

      <mapSources>

        <source type="XSD">

          <schema location="POTest.xsd"/>

          <rootElement name="POTestProcessRequest" namespace="http://xmlns.oracle.com/POTest"/>

        </source>

      </mapSources>

      <mapTargets>

        <target type="XSD">

          <schema location="POTest.xsd"/>

          <rootElement name="POTestProcessResponse" namespace="http://xmlns.oracle.com/POTest"/>

        </target>

      </mapTargets>

      <!-- GENERATED BY ORACLE XSL MAPPER 10.1.3.3.0(build 070615.0525) AT [THU OCT 17 10:20:35 GMT 2013]. -->

    ?>

    <xsl:stylesheet version="1.0"

                    xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions"

                    xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"

                    xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"

                    xmlns:ns1="http://xmlns.oracle.com/POTest"

                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

                    xmlns:ora="http://schemas.oracle.com/xpath/extension"

                    xmlns:ehdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.esb.server.headers.ESBHeaderFunctions"

                    xmlns:ns0="http://www.w3.org/2001/XMLSchema"

                    xmlns:orcl="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"

                    xmlns:ids="http://xmlns.oracle.com/bpel/services/IdentityService/xpath"

                    xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath"

                    exclude-result-prefixes="xsl ns1 ns0 xref xp20 bpws ora ehdr orcl ids hwf">

      <xsl:template match="/">

          <ns1:POTestProcessResponse>

          <xsl:attribute name="OrderDate">

            <xsl:value-of select="/ns1:POTestProcessRequest/@OrderDate"/>

          </xsl:attribute>

          <ns1:name>

            <xsl:value-of select="/ns1:POTestProcessRequest/ns1:name"/>

          </ns1:name>

          <ns1:street>

            <xsl:value-of select="/ns1:POTestProcessRequest/ns1:street"/>

          </ns1:street>

          <ns1:city>

            <xsl:value-of select="/ns1:POTestProcessRequest/ns1:city"/>

          </ns1:city>

          <ns1:state>

            <xsl:value-of select="/ns1:POTestProcessRequest/ns1:state"/>

          </ns1:state>

          <ns1:zip>

            <xsl:value-of select="/ns1:POTestProcessRequest/ns1:zip"/>

          </ns1:zip>

        </ns1:POTestProcessResponse>

      

      </xsl:template>

     

        <xsl:strip-space elements="*" />

    <xsl:template match="*">

    <xsl:if test=".!='' or count(@*)!=0">

      <xsl:copy>

       <xsl:apply-templates select="*|@*|text()" />

      </xsl:copy>

    </xsl:if>

    </xsl:template>

    <xsl:template match="@*">

    <xsl:copy-of select="." />

    </xsl:template>

    <xsl:template match="text()">

    <xsl:value-of select="." />

    </xsl:template>

     

     

     

     

    </xsl:stylesheet>

  • 3. Re: Need to exclude the empty elements after mapping in xslt.
    tsuji Journeyer
    Currently Being Moderated

    Before I try to comment on the errors, I need to bring up an improvement to the set of templates that I proposed to close a loophole. I would strengthen the test condition of the xsl:if element.

     

    <xsl:template match="*">

    <!-- instead of this, replace with the following line.

    <xsl:if test=".!='' or count(@*)!=0">

    -->

    <xsl:if test=".!='' or count(.//@*)!=0">

      <xsl:copy>

       <xsl:apply-templates select="*|@*|text()" />

      </xsl:copy>

    </xsl:if>

    </xsl:template>

     

    With that behind, some comments are in order.

     

    [0] What I had in mind is that the set of templates occupies the whole body of the xsl document inside the root xsl:stylesheet, except for instance you might need xsl:output or some pi as shown. That is what I meant, rightly or wrongly.

     

    [1]

    quote

    Line Number:(55) : Error: "xsl:strip-space" XSL Element Currently not Supported

    unquote

    That we can deal with without using xsl:strip-space by everywhere replacing text value by adding normalize-space().

    <!--

    <xsl:strip-space elements="*" />

    -->

    <xsl:template match="*">

    <xsl:if test="normalize-space(.) != '' or count(.//@*) != 0">

      <xsl:copy>

       <xsl:apply-templates select="*|@*|text()" />

      </xsl:copy>

    </xsl:if>

    </xsl:template>

    <xsl:template match="@*">

      <xsl:copy-of select="." />

    </xsl:template>

    <xsl:template match="text()">

      <xsl:value-of select="normalize-space()" />

    </xsl:template>

     

    [2]

    quote

    Line Number:(31) : Error: <xsl:template match="/"> and <xsl:template name="..."> are the only permitted <template> elements in the XSL

    unquote

    I never have encountered an xslt engine or in an operation environment with that restriction, so I cannot propose anything constructive. It is weird to say the least.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points