[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

WG: Nested Grouping of "flat" input

Subject: WG: Nested Grouping of "flat" input
From: Thomas Zöchling <thomas.zoechling@xxxxxx>
Date: Thu, 9 Dec 2004 12:08:13 +0100
title bookmarks
Hi List!
I am working on a bookmark manager, that is built around  XBEL
(http://pyxml.sourceforge.net/topics/xbel/).
The server-side part of our application needs to store the bookmark data in
a relational database.
But as XBEL defines a nested hierarchy, which cannot be stored in the
database directly, we had to introduce a flat version of the XBEL data.
Now our problem is, that we need to go the other way round, and extract the
path of a bookmark from our flat xml file, and restore the XBEL hierarchy
from it.

User( browser) -> XBEL -> flat format -> database -> flat -> XBEL -> all
other formats

Summary: Create a XML structured hierarchy from a path.

Examples:

XBEL:

<?xml version="1.0" encoding="UTF-8"?>
<xbel version="1.0">
<title>Bookmarks</title>
<older folded="yes">
<title>Sample2</title>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"><title>Mozilla Firefox Startseite</title></bookmark>
</folder>
<folder folded="yes">
<title>Sample</title>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"><title>Test</title></bookmark>
<folder folded="yes">
<title>FolderInSample</title>
</folder>
</folder>
<folder folded="yes">
<title>Bookmarks Toolbar Folder</title>
<bookmark href="http://slashdot.org/"><title>Slashdot: News for nerds, stuff
that matters</title></bookmark>
<bookmark href="http://www.heise.de/"><title>heise online</title></bookmark>
<bookmark href="http://futurezone.orf.at/"><title>ORF ON
Futurezone</title></bookmark>
</folder>
</xbel>

Flat XBEL:

<?xml version="1.0" encoding="utf-8"?>
<xbelflat version="1.0">
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official" name="Mozilla Firefox Startseite"
pfad="Bookmarks/Sample2/"></bookmark>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official" name="Test" pfad="Bookmarks/Sample/"></bookmark>
<bookmark href="http://slashdot.org/" name="Slashdot: News for nerds, stuff
that matters" pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
<bookmark href="http://www.heise.de/" name="heise online"
pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
<bookmark href="http://futurezone.orf.at/" name="ORF ON Futurezone"
pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
</xbelflat>

The xbelflat should be transformed back to XBEL:

What I can now:
- Split the path (@pfad) and output it in folders
- Group the bookmarks

What I cannot:
- Do the whole transform in one stylesheet
- Recreate the correct hierarchy (currently everything is flat grouped)


XSLT stylesheets:

Extracts the folder Names from the @pfad (=path) attribute

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:template name="root" match="xbelflat">
            <xbelflat version="1.0">
                        <xsl:call-template name="bm"></xsl:call-template>
            </xbelflat>
  </xsl:template>

  <xsl:template name="bm">
            <xsl:for-each select="bookmark">
                        <xsl:apply-templates/>

                        <xsl:call-template name="links">
                           <xsl:with-param name="str" select="@pfad"/>
                           <xsl:with-param name="pos"
select="position()-1"/>
                        </xsl:call-template>
        </xsl:for-each>
        <xsl:apply-templates/>
  </xsl:template>

  <xsl:template name="links">
    <xsl:param name="str"/>
    <xsl:param name="pos"/>
    <xsl:variable name="bmName" select="@name"/>

    <xsl:if test="position() != 1 ">

    </xsl:if>

    <xsl:choose>
      <xsl:when test="contains($str,'/') and
$bmName!=substring-before($str,'/')">
       <folder>
                        <xsl:attribute name="pfad"><xsl:value-of
select="substring-before($str,'/')"/></xsl:attribute>
        <xsl:call-template name="links">
          <xsl:with-param name="str" select="substring-after($str,'/')"/>
        </xsl:call-template>
        </folder>
      </xsl:when>
      <xsl:otherwise>
                        <xsl:attribute name="href"><xsl:value-of
select="@href"></xsl:value-of></xsl:attribute><xsl:value-of
select="following-sibling"/>
        <xsl:apply-templates/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Output of the above

<?xml version="1.0" encoding="UTF-16"?>
<xbelflat version="1.0">
<folder pfad="Bookmarks">
<folder pfad="Sample2"
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Sample"
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://slashdot.org/"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://www.heise.de/"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://futurezone.orf.at/"></folder>
</folder>
</xbelflat>

Second Stylesheet:
Groups the Bookmarks (But any structure information is lost here)

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

<xsl:key name="distinct" match="folder" use="@pfad"/>
<xsl:template match="/">
<xbel version="1.0">

<!--<xsl:for-each select="/xbelflat/folder/folder/folder[generate-id(.) =
generate-id(key('distinct',@pfad))]"> -->
<xsl:for-each select="xbelflat//folder[generate-id(.) =
generate-id(key('distinct',@pfad))]">

<folder>
                                   <xsl:value-of select="@pfad"/>
                        <xsl:variable name="currPath">
                                   <xsl:value-of select="@pfad"/>
                        </xsl:variable>
                        <xsl:variable name="lstBookmark"
select="//folder[@pfad=$currPath]"/>
                        <xsl:call-template name="DistinctedBookmarks">
                                   <xsl:with-param name="lstBookmark"
select="$lstBookmark" />
                        </xsl:call-template>
</folder>
            </xsl:for-each>
</xbel>
</xsl:template>

<xsl:template name="DistinctedBookmarks">
            <xsl:param name="lstBookmark"/>
            <xsl:for-each select="$lstBookmark">
                        <xsl:if test="@href!=''">
                                   <xsl:element name="bookmark">

                                                           <xsl:attribute
name="href"><xsl:value-of select="@href"/></xsl:attribute>
                                                           <xsl:attribute
name="name"><xsl:value-of select="@name"/></xsl:attribute>

                                   </xsl:element>
                                   </xsl:if>
                          </xsl:for-each>
</xsl:template>

</xsl:stylesheet>


Output:
Hi List!
I am working on a bookmark manager, that is built around  XBEL
(http://pyxml.sourceforge.net/topics/xbel/).
The server-side part of our application needs to store the bookmark data in
a relational database.
But as XBEL defines a nested hierarchy, which cannot be stored in the
database directly, we had to introduce a flat version of the XBEL data.
Now our problem is, that we need to go the other way round, and extract the
path of a bookmark from our flat xml file, and restore the XBEL hierarchy
from it.

User( browser) -> XBEL -> flat format -> database -> flat -> XBEL -> all
other formats

Summary: Create a XML structured hierarchy from a path.

Examples:

XBEL:

<?xml version="1.0" encoding="UTF-8"?>
<xbel version="1.0">
<title>Bookmarks</title>
<older folded="yes">
<title>Sample2</title>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"><title>Mozilla Firefox Startseite</title></bookmark>
</folder>
<folder folded="yes">
<title>Sample</title>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"><title>Test</title></bookmark>
<folder folded="yes">
<title>FolderInSample</title>
</folder>
</folder>
<folder folded="yes">
<title>Bookmarks Toolbar Folder</title>
<bookmark href="http://slashdot.org/"><title>Slashdot: News for nerds, stuff
that matters</title></bookmark>
<bookmark href="http://www.heise.de/"><title>heise online</title></bookmark>
<bookmark href="http://futurezone.orf.at/"><title>ORF ON
Futurezone</title></bookmark>
</folder>
</xbel>

Flat XBEL:

<?xml version="1.0" encoding="utf-8"?>
<xbelflat version="1.0">
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official" name="Mozilla Firefox Startseite"
pfad="Bookmarks/Sample2/"></bookmark>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official" name="Test" pfad="Bookmarks/Sample/"></bookmark>
<bookmark href="http://slashdot.org/" name="Slashdot: News for nerds, stuff
that matters" pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
<bookmark href="http://www.heise.de/" name="heise online"
pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
<bookmark href="http://futurezone.orf.at/" name="ORF ON Futurezone"
pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
</xbelflat>

The xbelflat should be transformed back to XBEL:

What I can now:
- Split the path (@pfad) and output it in folders
- Group the bookmarks

What I cannot:
- Do the whole transform in one stylesheet
- Recreate the correct hierarchy (currently everything is flat grouped)


XSLT stylesheets:

Extracts the folder Names from the @pfad (=path) attribute

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:template name="root" match="xbelflat">
            <xbelflat version="1.0">
                        <xsl:call-template name="bm"></xsl:call-template>
            </xbelflat>
  </xsl:template>

  <xsl:template name="bm">
            <xsl:for-each select="bookmark">
                        <xsl:apply-templates/>

                        <xsl:call-template name="links">
                           <xsl:with-param name="str" select="@pfad"/>
                           <xsl:with-param name="pos"
select="position()-1"/>
                        </xsl:call-template>
        </xsl:for-each>
        <xsl:apply-templates/>
  </xsl:template>

  <xsl:template name="links">
    <xsl:param name="str"/>
    <xsl:param name="pos"/>
    <xsl:variable name="bmName" select="@name"/>

    <xsl:if test="position() != 1 ">

    </xsl:if>

    <xsl:choose>
      <xsl:when test="contains($str,'/') and
$bmName!=substring-before($str,'/')">
       <folder>
                        <xsl:attribute name="pfad"><xsl:value-of
select="substring-before($str,'/')"/></xsl:attribute>
        <xsl:call-template name="links">
          <xsl:with-param name="str" select="substring-after($str,'/')"/>
        </xsl:call-template>
        </folder>
      </xsl:when>
      <xsl:otherwise>
                        <xsl:attribute name="href"><xsl:value-of
select="@href"></xsl:value-of></xsl:attribute><xsl:value-of
select="following-sibling"/>
        <xsl:apply-templates/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Output of the above

<?xml version="1.0" encoding="UTF-16"?>
<xbelflat version="1.0">
<folder pfad="Bookmarks">
<folder pfad="Sample2"
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Sample"
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://slashdot.org/"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://www.heise.de/"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://futurezone.orf.at/"></folder>
</folder>
</xbelflat>

Second Stylesheet:
Groups the Bookmarks (But any structure information is lost here)

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

<xsl:key name="distinct" match="folder" use="@pfad"/>
<xsl:template match="/">
<xbel version="1.0">

<!--<xsl:for-each select="/xbelflat/folder/folder/folder[generate-id(.) =
generate-id(key('distinct',@pfad))]"> -->
<xsl:for-each select="xbelflat//folder[generate-id(.) =
generate-id(key('distinct',@pfad))]">

<folder>
                                   <xsl:value-of select="@pfad"/>
                        <xsl:variable name="currPath">
                                   <xsl:value-of select="@pfad"/>
                        </xsl:variable>
                        <xsl:variable name="lstBookmark"
select="//folder[@pfad=$currPath]"/>
                        <xsl:call-template name="DistinctedBookmarks">
                                   <xsl:with-param name="lstBookmark"
select="$lstBookmark" />
                        </xsl:call-template>
</folder>
            </xsl:for-each>
</xbel>
</xsl:template>

<xsl:template name="DistinctedBookmarks">
            <xsl:param name="lstBookmark"/>
            <xsl:for-each select="$lstBookmark">
                        <xsl:if test="@href!=''">
                                   <xsl:element name="bookmark">

                                                           <xsl:attribute
name="href"><xsl:value-of select="@href"/></xsl:attribute>
                                                           <xsl:attribute
name="name"><xsl:value-of select="@name"/></xsl:attribute>

                                   </xsl:element>
                                   </xsl:if>
                          </xsl:for-each>
</xsl:template>

</xsl:stylesheet>


Output:
Hi List!
I am working on a bookmark manager, that is built around  XBEL
(http://pyxml.sourceforge.net/topics/xbel/).
The server-side part of our application needs to store the bookmark data in
a relational database.
But as XBEL defines a nested hierarchy, which cannot be stored in the
database directly, we had to introduce a flat version of the XBEL data.
Now our problem is, that we need to go the other way round, and extract the
path of a bookmark from our flat xml file, and restore the XBEL hierarchy
from it.

User( browser) -> XBEL -> flat format -> database -> flat -> XBEL -> all
other formats

Summary: Create a XML structured hierarchy from a path.

Examples:

XBEL:

<?xml version="1.0" encoding="UTF-8"?>
<xbel version="1.0">
<title>Bookmarks</title>
<older folded="yes">
<title>Sample2</title>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"><title>Mozilla Firefox Startseite</title></bookmark>
</folder>
<folder folded="yes">
<title>Sample</title>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"><title>Test</title></bookmark>
<folder folded="yes">
<title>FolderInSample</title>
</folder>
</folder>
<folder folded="yes">
<title>Bookmarks Toolbar Folder</title>
<bookmark href="http://slashdot.org/"><title>Slashdot: News for nerds, stuff
that matters</title></bookmark>
<bookmark href="http://www.heise.de/"><title>heise online</title></bookmark>
<bookmark href="http://futurezone.orf.at/"><title>ORF ON
Futurezone</title></bookmark>
</folder>
</xbel>

Flat XBEL:

<?xml version="1.0" encoding="utf-8"?>
<xbelflat version="1.0">
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official" name="Mozilla Firefox Startseite"
pfad="Bookmarks/Sample2/"></bookmark>
<bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official" name="Test" pfad="Bookmarks/Sample/"></bookmark>
<bookmark href="http://slashdot.org/" name="Slashdot: News for nerds, stuff
that matters" pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
<bookmark href="http://www.heise.de/" name="heise online"
pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
<bookmark href="http://futurezone.orf.at/" name="ORF ON Futurezone"
pfad="Bookmarks/Bookmarks Toolbar Folder/"></bookmark>
</xbelflat>

The xbelflat should be transformed back to XBEL:

What I can now:
- Split the path (@pfad) and output it in folders
- Group the bookmarks

What I cannot:
- Do the whole transform in one stylesheet
- Recreate the correct hierarchy (currently everything is flat grouped)


XSLT stylesheets:

Extracts the folder Names from the @pfad (=path) attribute

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:template name="root" match="xbelflat">
            <xbelflat version="1.0">
                        <xsl:call-template name="bm"></xsl:call-template>
            </xbelflat>
  </xsl:template>

  <xsl:template name="bm">
            <xsl:for-each select="bookmark">
                        <xsl:apply-templates/>

                        <xsl:call-template name="links">
                           <xsl:with-param name="str" select="@pfad"/>
                           <xsl:with-param name="pos"
select="position()-1"/>
                        </xsl:call-template>
        </xsl:for-each>
        <xsl:apply-templates/>
  </xsl:template>

  <xsl:template name="links">
    <xsl:param name="str"/>
    <xsl:param name="pos"/>
    <xsl:variable name="bmName" select="@name"/>

    <xsl:if test="position() != 1 ">

    </xsl:if>

    <xsl:choose>
      <xsl:when test="contains($str,'/') and
$bmName!=substring-before($str,'/')">
       <folder>
                        <xsl:attribute name="pfad"><xsl:value-of
select="substring-before($str,'/')"/></xsl:attribute>
        <xsl:call-template name="links">
          <xsl:with-param name="str" select="substring-after($str,'/')"/>
        </xsl:call-template>
        </folder>
      </xsl:when>
      <xsl:otherwise>
                        <xsl:attribute name="href"><xsl:value-of
select="@href"></xsl:value-of></xsl:attribute><xsl:value-of
select="following-sibling"/>
        <xsl:apply-templates/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Output of the above

<?xml version="1.0" encoding="UTF-16"?>
<xbelflat version="1.0">
<folder pfad="Bookmarks">
<folder pfad="Sample2"
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Sample"
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://slashdot.org/"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://www.heise.de/"></folder>
</folder>
<folder pfad="Bookmarks">
<folder pfad="Bookmarks Toolbar Folder"
href="http://futurezone.orf.at/"></folder>
</folder>
</xbelflat>

Second Stylesheet:
Groups the Bookmarks (But any structure information is lost here)

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

<xsl:key name="distinct" match="folder" use="@pfad"/>
<xsl:template match="/">
<xbel version="1.0">

<!--<xsl:for-each select="/xbelflat/folder/folder/folder[generate-id(.) =
generate-id(key('distinct',@pfad))]"> -->
<xsl:for-each select="xbelflat//folder[generate-id(.) =
generate-id(key('distinct',@pfad))]">

<folder>
                                   <xsl:value-of select="@pfad"/>
                        <xsl:variable name="currPath">
                                   <xsl:value-of select="@pfad"/>
                        </xsl:variable>
                        <xsl:variable name="lstBookmark"
select="//folder[@pfad=$currPath]"/>
                        <xsl:call-template name="DistinctedBookmarks">
                                   <xsl:with-param name="lstBookmark"
select="$lstBookmark" />
                        </xsl:call-template>
</folder>
            </xsl:for-each>
</xbel>
</xsl:template>

<xsl:template name="DistinctedBookmarks">
            <xsl:param name="lstBookmark"/>
            <xsl:for-each select="$lstBookmark">
                        <xsl:if test="@href!=''">
                                   <xsl:element name="bookmark">

                                                           <xsl:attribute
name="href"><xsl:value-of select="@href"/></xsl:attribute>
                                                           <xsl:attribute
name="name"><xsl:value-of select="@name"/></xsl:attribute>

                                   </xsl:element>
                                   </xsl:if>
                          </xsl:for-each>
</xsl:template>

</xsl:stylesheet>


Output:

<?xml version="1.0" encoding="UTF-16"?><xbel version="1.0">
<folder>Bookmarks</folder>
<folder>Sample2
            <bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official" name="" /></folder>
<folder>Sample
            <bookmark
href="http://www.google.at/firefox?client=firefox-a&amp;rls=org.mozilla:de-D
E:official" name="" /></folder>
<folder>Bookmarks Toolbar Folder<bookmark href="http://slashdot.org/"
name="" />
            <bookmark href="http://www.heise.de/" name="" />
            <bookmark href="http://futurezone.orf.at/" name="" /></folder>
</xbel>


How can I get back a Tee structure?

Bookmarks
            Sample2
            Sample
                        .
            BookmarkToolbarFolder
                        .
                        .


Thanks in advance

Thomas

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.