xsl-list
[Top] [All Lists]

Re: Another <xsl:key> problem

2005-09-27 23:07:52
Hi Aaron,

I have looked a bit on your problem.

Presumably you have:
<text:p>
    <bookmark-start id="bib1"/>
    <user-field name="bib-reference">Ref</user-field>
</text:p>
...
<text:p>
    <user-field name="sb:date">Date</user-field>
    <user-text>1988</user-text>
    <bookmark-end id="bib1"/>
</text:p>
<text:p>
    <bookmark-start id="bib2"/>
    <user-field name="bib-reference">Ref</user-field>
</text:p>
...
<text:p>
    <user-field name="sb:date">Date</user-field>
    <user-text>1988</user-text>
    <bookmark-end id="bib2"/>
</text:p>
....

From what I gather, you have a flat structure that you want to make
hierarchic. Therefore I assume that the bookmarks cannot be nested.
This solution does not use keys, but rather find the logical children
of the bookmarks.
I have also presumed that the structure throughout is the same.

But in all, I would say that if you have any influence on the input
XML, then you should change it. There is nothing in the structures or
attributes that tells that "sb:title" is the child of
"sb:contribution" instead of "sb:authors". This makes a generic
solution impossible.

I have scetched a more generic solution which does not at all do what
you require, but I hope this is some inspiration. Namely, it does not
have an "before host" and "after host" part.

<xsl:template match="root">
  <xsl:apply-templates select="p[bookmark-start]" mode="bookmark"/>
</xsl:template>

<xsl:template match="p" mode="bookmark">
  <xsl:element name="{user-field[1]/@name}">
    <xsl:apply-templates
select="following-sibling::p[preceding-sibling::p[bookmark-start[(_at_)id=current()/@id]]"
mode="children"/> <!-- Should be a key -->
  </xsl:element>
</xsl:template>

<!-- Should have two templates, one for before host, and one for after host -->
<xsl:template match="p" mode="children">
  <xsl:element name="{user-field[1]/@name}">
    <xsl:choose>
      <xsl:when test="user-field[position()&gt;1]"> <!-- more
user-fields => leaf -->
        <xsl:apply-templates select="user-field[position()&gt;1]" mode="leaf"/>
      </xsl:when>
      <xsl:otherwise>
        <!-- More logical children. Caveat about "host" element applies -->
        <xsl:apply-templates
select="following-sibling::p[preceding-sibling::p[bookmark-start[(_at_)id=current()/@id]]"
mode="children"/>
      </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="user-field" mode="leaf">
   <xsl:element name="{(_at_)name}">
     <xsl:value-of select="following-sibling::user-text"/>
  </xsl:element>
</xsl:template>

I hope this is some help for your problem.
Regards,
Ragulf Pickaxe :-)

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