xsl-list
[Top] [All Lists]

[xsl] Extracting a fragment between milestones from a complex structure.

2011-02-28 16:00:34
I am looking for a template which allows me to extract a single page, as
marked by milestone elements <pb n="12"/> from a complex structure. Note
that the milestone elements may occur in different parents. I want all
the parent nodes, and everything between the <pb n="12"/> and the next
<pb/> element

For example, when applying the extract method with as parameter "12" on
the following sample

<TEI>
    <front>...</front>
    <body>
        <div1>
            <head>Blah</head>
            Blah blah <pb n="12"/> blah blah.
        </div1>
        <div1>
            Blah blah blah blah.
        </div1>
        <div1>
            Blah <hi>blah <pb n="13"/> blah</hi> blah.
        </div1>
    </body>
    <back>...</back>
</TEI>

It should return:

<TEI>
    <body>
        <div1>
            <pb n="12"/> blah blah.
        </div1>
        <div1>
            Blah blah blah blah.
        </div1>
        <div1>
            Blah <hi>blah <pb n="13"/></hi>
        </div1>
    </body>
</TEI>

The idea is that it will copy only elements that are a ancestor of
either <pb/> and follow the first <pb/> and precede the second <pb/>.
The problem I face is formulating a nice XPath to select those elements.

What I have so-far is a few templates that certainly do not behave as
expected:

    <xsl:template name="extract-page">
        <xsl:param name="n"/>

            <xsl:call-template name="extract-from-to">
                <xsl:with-param name="from" select="//pb[@n=$n]"/>
                <xsl:with-param name="to"
select="(//pb[preceding::pb[@n=$n]])[1]"/>
            </xsl:call-template>

    </xsl:template>

    <xsl:template name="extract-from-to">
        <xsl:param name="from"/>
        <xsl:param name="to"/>

            <xsl:copy-of select="$from"/>
            <xsl:copy-of select="$to"/>

            <xsl:apply-templates mode="copy"
                select="//*[(ancestor::node()=$from and
ancestor::node()=$to) or (following::node()=$from and
preceding::node()=$to)]">
            </xsl:apply-templates>
    </xsl:template>


    <xsl:template mode="copy" match="text()|*">
        <xsl:copy>
            <xsl:apply-templates mode="copy"/>
        </xsl:copy>
    </xsl:template>


Any hints or suggestions will be appreciated.

Jeroen Hellingman



--~------------------------------------------------------------------
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>