Solved

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

Posted on 2016-08-13
10
46 Views
Last Modified: 2016-08-14
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
Comment
Question by:ethar1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
10 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 41755147
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
 

Author Comment

by:ethar1
ID: 41755480
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
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 41755559
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
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!

 
LVL 60

Expert Comment

by:Geert Bormans
ID: 41755602
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
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 41755603
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
 

Author Comment

by:ethar1
ID: 41755610
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
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 41755613
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
 

Author Comment

by:ethar1
ID: 41755614
ok, Thanks
in the XML you use there is a <p> where it is not in my source.
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 41755617
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
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 41755618
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!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Test ddwrt:UserLookup 1 71
Wordpress Cron - Send XML Data to external server FTP 3 33
xml files 7 53
I'm using XML(xslt) - How to fix the BOM issue 5 22
The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question