xsl-list
[Top] [All Lists]

[xsl] Comparing direct ancestors

2012-05-24 10:40:17
Hi List,

Thanks in advance for any help.

I've been banging my head around this problem for awhile now and could
use any advice anyone is willing to give. I have the following xml:

<?xml version="1.0"?>
<root>
        <change-begin/>
        <a>
                <p>Foo<change-end/></p>
        </a>
        <change-begin/>
        <b>
                <d>
                        <t>Bar</t>
                </d>
                <d>
                        <t>Foo</t>
                </d>
        </b>
        <change-end/>
        <p>Nothing <change-begin/>to worry<change-end/> about</p>
</root>

I need to write an xslt (2.0 is fine) that will "move" the
<change-begin/> and <change-end/> elements to be children of the
nearest pre-defined allowable element. So in the example above I have
<p> and <t> as elements that allow the <change-begin/> and
<change-end/> elements. The output should look like this:

<?xml version="1.0"?>
<root>
        <a>
                <p><change-begin/>Foo<change-end/></p>
        </a>
        <b>
                <d>
                        <t><change-begin/>Bar</t>
                </d>
                <d>
                        <t>Foo<change-end/></t>
                </d>
        </b>
        <p>Nothing <change-begin/>to worry<change-end/> about</p>
</root>

My plan was a multi-pass stylesheet that first took care of the
<change-begin/> then went on to take care of the <change-ends/>. For
brevity I've limit this post to trying to deal with the
<change-begin/>:

<?xml version='1.0'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:variable name="allowed">
        <n>p</n>
        <n>t</n>
</xsl:variable>

<xsl:template match="/">
        <xsl:apply-templates select="root" mode="begins"/>
</xsl:template>

<xsl:template match="*" mode="begins">
<xsl:variable name="name" select="name()"/>
                <!-- ok here we narrow our field of vision -->
        <xsl:choose>
                        <!-- Only worry about elements that are possible 
candidates for
moving changes in -->
            <xsl:when test="$allowed/n[name() = $name]">
                <xsl:choose>
                                        <!-- Is a sibiling a change-begin tag, 
or are any ancestors
siblings a change-begin tag? -->
                                        <xsl:when 
test="preceding-sibling::change-begin or
(ancestor::*[preceding-sibling::change-begin])">
                                                <xsl:copy>
                                                        <change-begin/>
                                    <xsl:copy-of select="@*"/>
                                    <xsl:apply-templates mode="begins"/>
                                                </xsl:copy>
                                        </xsl:when>
                                        <xsl:otherwise>
                                <xsl:copy>
                                    <xsl:copy-of select="@*"/>
                                    <xsl:apply-templates mode="begins"/>
                                </xsl:copy>
                                        </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:copy-of select="@*"/>
                    <xsl:apply-templates mode="begins"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
</xsl:template>

<!-- remove the begins outside of allowable elements. -->
<xsl:template match="change-begin" mode="begins">
        <xsl:if test="parent::*[name() = $allowed/n/.]">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates mode="begins"/>
        </xsl:copy>
        </xsl:if>
</xsl:template>

</xsl:stylesheet>

So far it doesn't work and is fast becoming a bunch of spaghetti
<choose> statements. If anyone has any ideas I would love to hear
them.

Thanks

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>