Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 60
  • Last Modified:

Group all sequential comments all in one binder <p>, using XSL

Dear all,
Using XSL Need to group all sequential @LineItemType="COMMENTS" to one <p>  

here's the XML:
<children LineItemType="COMMENTS" FixText="'-------------------------------"/>
<children LineItemType="COMMENTS" FixText="' xxxxxxx  "/>
<children LineItemType="COMMENTS" FixText="'-------------------------------"/>
<children LineItemType="COMMENTS" FixText="  Dom rx"/>
<children LineItemType="COMMENTS" FixText="  Dom Where"/>
<children LineItemType="TEXT" FixText="Just Simple TEXT1"/>
<children LineItemType="Text" FixText="Just Simple TEXT2"/>
<children LineItemType="COMMENTS" FixText="'-------------------------------"/>
<children LineItemType="Text" FixText="Just Simple TEXT3"/>
<children LineItemType="Text" FixText="Just Simple TEXT4"/>

Open in new window


Thanks
0
ethar1
Asked:
ethar1
  • 7
  • 3
1 Solution
 
Geert BormansCommented:
Try this (XSLT2)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"></xsl:output>
    
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"></xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="*[children]">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:for-each-group select="*" group-adjacent="if(self::children and @LineItemType='COMMENTS') then('comments') else(generate-id())">
                <xsl:choose>
                    <xsl:when test="current-grouping-key() = 'comments'">
                        <p>
                            <xsl:copy-of select="current-group()"/>
                        </p>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:copy-of select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

Open in new window

0
 
ethar1Author Commented:
Dear Geert Bormans
Thanks for your reply.

I got this error
for-each-group' is not a recognized extension element. An error occurred at 101,14
0
 
Geert BormansCommented:
That is because you are likely not using xslt2
Xslt2 is now common use for almost ten years, so i assume xslt2 unless a different context is given

Solving this grouping issue is harder in xslt1

Please, in your questions specify the execution context
Please check if xslt2 can be used, if not i will do an xslt1 variant
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Geert BormansCommented:
I have assumed, you want this result using an XSLT1 (note that I wrapped your non wellformed XML in a root element to make it valid)

?xml version="1.0" encoding="UTF-8"?>
<root>
   <p>
      <children LineItemType="COMMENTS" FixText="'-------------------------------"/>
      <children LineItemType="COMMENTS" FixText="' xxxxxxx  "/>
      <children LineItemType="COMMENTS" FixText="'-------------------------------"/>
      <children LineItemType="COMMENTS" FixText="  Dom rx"/>
      <children LineItemType="COMMENTS" FixText="  Dom Where"/>
   </p>
   <children LineItemType="TEXT" FixText="Just Simple TEXT1"/>
   <children LineItemType="Text" FixText="Just Simple TEXT2"/>
   <p>
      <children LineItemType="COMMENTS" FixText="'-------------------------------"/>
   </p>
   <children LineItemType="Text" FixText="Just Simple TEXT3"/>
   <children LineItemType="Text" FixText="Just Simple TEXT4"/>
</root>

Open in new window

0
 
Geert BormansCommented:
This would be the code

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()[1]"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    
    <xsl:template match="children[@LineItemType='COMMENTS']">
        <p>
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates select="node()[1]"/>
            </xsl:copy>
            <xsl:apply-templates select="following-sibling::node()[1][self::children[@LineItemType='COMMENTS']]" mode="inner-p"/>
        </p>
        <xsl:apply-templates select="following-sibling::node()[not(self::children[@LineItemType='COMMENTS'])][1]"/>
    </xsl:template>
    
    <xsl:template match="children[@LineItemType='COMMENTS']" mode="inner-p">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()[1]"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1][self::children[@LineItemType='COMMENTS']]" mode="inner-p"/>
    </xsl:template>
        
    
    
</xsl:stylesheet>

Open in new window

0
 
ethar1Author Commented:
Dear Geert Bormans,
I got issues here :) , I am ready to open questions as much as you like to follow.
First issue , I am very confused about the xslt2 and xslt1 , is it enough to define
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >?
Actually I am using VC# 2013 to transform like this:
 
DOMDocument XMLSourceDataSingleDoc = new DOMDocument( );
XMLSourceDataSingleDoc.transformNode(SingleXSLFile);

Open in new window


Second Issue : Here's my XML:

?xml version="1.0" encoding="UTF-8"?>
<root>
      <children LineItemType="COMMENTS" FixText="'-------------------------------"/>
      <children LineItemType="COMMENTS" FixText="' xxxxxxx  "/>
      <children LineItemType="COMMENTS" FixText="'-------------------------------"/>
      <children LineItemType="COMMENTS" FixText="  Dom rx"/>
      <children LineItemType="COMMENTS" FixText="  Dom Where"/>
   <children LineItemType="TEXT" FixText="Just Simple TEXT1"/>
   <children LineItemType="Text" FixText="Just Simple TEXT2"/>
      <children LineItemType="COMMENTS" FixText="'-------------------------------"/>
   <children LineItemType="Text" FixText="Just Simple TEXT3"/>
   <children LineItemType="Text" FixText="Just Simple TEXT4"/>
</root>

Open in new window


And here's the output:
<p>
'-------------------------------
' xxxxxxx  
'-------------------------------
  Dom rx
  Dom Where
</p>
Just Simple TEXT1
Just Simple TEXT2
<p>'-------------------------------</p>
Just Simple TEXT3
Just Simple TEXT4

Open in new window


Thanks for your efforts
0
 
Geert BormansCommented:
No, you need a processor that supports XSLT2
VC# does not

I don't need you to open many question, I need you to be specific enough and do some of the work yourself

The XML you sent is exactly the one I used for testing

The output is not what comes out of my stylesheet
0
 
ethar1Author Commented:
ok, Thanks
in the XML you use there is a <p> where it is not in my source.
0
 
Geert BormansCommented:
In case the output you sent is "what you want" (please be clear in your questions)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()[1]"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    
    <xsl:template match="children">
        <xsl:text>&#10;</xsl:text>
        <xsl:value-of select="@FixText"/>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    
    <xsl:template match="children[@LineItemType='COMMENTS']">
        <p>
            <xsl:text>&#10;</xsl:text>
            <xsl:value-of select="@FixText"/>
             <xsl:apply-templates select="following-sibling::node()[1][self::children[@LineItemType='COMMENTS']]" mode="inner-p"/>
        </p>
        <xsl:apply-templates select="following-sibling::node()[not(self::children[@LineItemType='COMMENTS'])][1]"/>
    </xsl:template>
    
    <xsl:template match="children[@LineItemType='COMMENTS']" mode="inner-p">
        <xsl:text>&#10;</xsl:text>
        <xsl:value-of select="@FixText"/>
        <xsl:apply-templates select="following-sibling::node()[1][self::children[@LineItemType='COMMENTS']]" mode="inner-p"/>
    </xsl:template>
    
    
    
</xsl:stylesheet>

Open in new window

1
 
Geert BormansCommented:
I did not post any source, I only posted a result
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now