locked
Remove Empty Nodes In existing custom XSLT RRS feed

  • Question

  • Hi,

    I have already written custom XSLT for other purpose. But now after executing that i need to remove empty nodes from it. i tried to inserting sample code (for removing empty node),  but it is not working.

    <xsl:template match="/">
    <xsl:apply-templates select="/Delivery" />
    </xsl:template><xsl:template match="/DeliveryLeg">

    <xsl:template match="/Delivery">
    <ns0:DeliveryInst>
    <xsl:attribute name="DeliveryInstStatusType">
    <xsl:value-of select="INSTRUCTION_STATUS_TYPE/text()"/>
    </xsl:attribute>
    <ns0:DeliveryInstruction>
    ......
    .....
    ...
    .....
    </xsl:template>

    I tried calling template but it is throwing error since existing xslt code is too big and  <xsl:copyit is going into recursive mode.

     <xsl:template match="node()">
            <xsl:if test="count(descendant::text()[string-length(normalize-space(.))>0]|@*)">
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()" />
                </xsl:copy>
            </xsl:if>
        </xsl:template>
        <xsl:template match="@*">
            <xsl:copy />
        </xsl:template>
        <xsl:template match="text()">
            <xsl:value-of select="normalize-space(.)" />
        </xsl:template>

    How can i execute remove empty node xslt after finishing first xslt template ??

    BR,

    Sachin

    Thursday, December 12, 2013 12:15 PM

Answers

All replies

  • A quick thought..

    If executing the above XSLT template with your existing XSLT is an issue, then you can consider executing this XSLT template which removes empty elements in another map after your primary map which has large XSLT.

    Something like executing two maps, one for mapping the element with your existing large XSLT and another just to remove empty multiple elements. In the second map both the input and the destination schema would be same.


    If this answers your question please mark it accordingly. If this post is helpful, please vote as helpful.

    Thursday, December 12, 2013 12:43 PM
  • Have a look at this blog post Removing Empty Nodes

    Colin Meade (MCTS BizTalk Server) http://midheach.wordpress.com

    Thursday, December 12, 2013 1:02 PM
  • To answer your specific question, you can't do that because the output is already generated.

    The link provided by Colin Meade is your best option. It's simple solution is to not copy empty nodes in the first place.

    Thursday, December 12, 2013 1:25 PM
    Moderator
  • If I am not wrong, Colin Meade is pointing to the same XSLT which questioner is already using which outputs the error. Better alternate to call this XSLT as I suggested in another map after mapping the output using the first large XSLT.


    If this answers your question please mark it accordingly. If this post is helpful, please vote as helpful.

    Thursday, December 12, 2013 1:36 PM
  • The XSLT is the same but where it is being executed is different. The link I posted provides step-by-step instructions which should help Sachin achieve his aim.

    Colin Meade (MCTS BizTalk Server) http://midheach.wordpress.com

    Thursday, December 12, 2013 2:22 PM
  • Isnt it possible to execute the first XSLT in a map and put the cleanup XSLT in a custom pipeline component?

    Then you can also reuse the Cleaner pipeline for furture projects. I am using this construction with the following cleanup code in a custom pipeline component:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
        <xsl:strip-space elements="*"/>
        <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="*[not(normalize-space())]"/>
    </xsl:stylesheet>

    Thursday, December 12, 2013 2:53 PM
  • The meaningful difference appears to be:

    test="count(descendant::text()[string-length(normalize-space(.))>0]|@*)"

    which tests the text() for any non-whitespace length before applying the attrib or element templates.

    I think this will also skip empty elements even if it has attribute values which may be a problem.

    Thursday, December 12, 2013 3:08 PM
    Moderator