Question

I need to identify partial and impartial descendants from XSLT2.0? i like to group all impartial descendant node. my input/output expectation from below coding.

impartial example: input1

<p><b><i><font><color>This is impartial paragraph example</color></font></i></b></p>

output1 expect:

<p><property><b/></i><font/><color/></property><text>This is impartial paragraph example</text></p>

partial example: input2

<p><b><color><font><bi>This is partial style example</bi>non-bi</font>non-font</color>non-color</b></p>

output2 expect:

<p><property><b/></property><text><color><font><bi>This is partial style example</bi>non-bi</font>non-font</color>non-color</text></p>

input3

<p>non-bold<b><color><font><bi>This is partial style example</bi>non-bi</font></color>non-color</b></p>

output3 expect:

<p><property/><text>non-bold<b><color><font><bi>This is partial style example</bi>non-bi</font>non-font</color>non-color</b></text></p>

Please help me do this!

Was it helpful?

Solution

This stylesheet:

<xsl:stylesheet version='1.0' xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>

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

    <xsl:template match="root/p">
        <xsl:choose>
            <xsl:when test="child::text()">
                <xsl:copy>
                    <property/>
                    <text><xsl:copy-of select="child::node()"/></text>
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <property>
                        <xsl:for-each select="descendant::*">
                            <xsl:choose>
                                <xsl:when test="not(current()/following-sibling::text())">
                                    <xsl:element name="{local-name()}"/>
                                </xsl:when>
                            </xsl:choose>
                        </xsl:for-each>
                    </property>
                    <text>
                        <xsl:choose>
                            <xsl:when test="descendant::text()[not(preceding-sibling::*)][not(following-sibling::*)][parent::node()[not(following-sibling::text())]]">
                                <xsl:value-of select="descendant::text()[not(following-sibling::*)][not(preceding-sibling::*)][parent::node()[not(following-sibling::text())]]"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:copy-of select="descendant::node()[following-sibling::text()][1]"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </text>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

when applied to this input:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <p><b><i><font><color>This is impartial paragraph example</color></font></i></b></p>

    <p><b><color><font><bi>This is partial style example</bi>non-bi</font>non-font</color>non-color</b></p>

    <p>non-bold<b><color><font><bi>This is partial style example</bi>non-bi</font></color>non-color</b></p>
</root>

produces:

<?xml version="1.0" encoding="utf-8"?>
<p>
   <property>
      <b/>
      <i/>
      <font/>
      <color/>
   </property>
   <text>This is impartial paragraph example</text>
</p>
<p>
   <property>
      <b/>
   </property>
   <text>
      <color>
         <font>
            <bi>This is partial style example</bi>non-bi</font>non-font</color>
   </text>
</p>
<p>
   <property/>
   <text>non-bold<b>
         <color>
            <font>
               <bi>This is partial style example</bi>non-bi</font>
         </color>non-color</b>
   </text>
</p>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top