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

Re: is there a way to output XML with invalid qnames?

Subject: Re: is there a way to output XML with invalid qnames?
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Fri, 06 Nov 2009 21:07:57 -0500
Re:  is there a way to output XML with invalid qnames?
At 2009-11-06 16:57 -0800, Jessica Britton wrote:
I'm trying to format XML files so that I can display them as examples in a wiki. I'd like the element names in the examples to link to other wiki pages, so I'm trying to figure out the best way to take source like this:

<ns:elementName1>
    <ns:elementName2>value</ns:elementName2>
</ns:elementName1>


And get output like this:


<[ns:elementName1|page 1]>
    <[ns:elementName2|page 2]>value</ns:elementName2>
</ns:elementName1>

This was an interesting challenge! Especially coming up with monotonically increasing page number references for unique element names across the instance.


Of course, "[ns:elementName|page]" isn't a valid qname so just trying to rename the elements in an XML to XML transform doesn't work.
...
Before I give myself a headache trying to figure it out, I was wondering if anyone could suggest a better approach I should look into.

I think the example below suits your needs, though I'm making guesses. As a more extensive test I ran the stylesheet through itself in order to have a larger test. This isn't a very rigourous test, and I haven't checked nearly all the edge cases but it should do a lot for you as it stands and may meet your needs.


I hope this helps.

. . . . . . . . . . . Ken


T:\ftemp>type jessica.xml <ns:elementName1 xmlns:ns="urn:X-Jessica"> <ns:elementName2>value</ns:elementName2> </ns:elementName1>

T:\ftemp>call xslt jessica.xml xml2wiki.xsl
<[ns:elementName1|page 1] xmlns:ns="urn:X-Jessica">
    <[ns:elementName2|page 2]>value</ns:elementName2>
</ns:elementName1>
T:\ftemp>type xml2wiki.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<xsl:output method="text"/>

<xsl:key name="names" match="*" use="name(.)"/>

<xsl:template match="*">
  <!--reconstitute the element start tag-->
  <xsl:text>&lt;[</xsl:text>
  <xsl:value-of select="name(.)"/>|page <xsl:text/>
  <!--find the first in document order-->
  <xsl:variable name="first"
                select="key('names',name(.))[1]"/>
  <!--determine its ordinal based on the uniqueness of element names-->
  <xsl:value-of select="count(
                        ($first/preceding::* | $first/ancestor::*)
                        [generate-id(.)=
                         generate-id(key('names',name(.))[1])]) + 1"/>
  <xsl:text>]</xsl:text>
  <!--reconstitute the namespaces-->
  <xsl:for-each select="namespace::*[not(.=../../namespace::*) and
                                     name(.)!='xml']">
    <xsl:value-of select="concat(' ','xmlns')"/>
    <xsl:if test="name(.)">:<xsl:value-of select="name(.)"/></xsl:if>
    <xsl:value-of select="concat('=&#x22;',.,'&#x22;')"/>
  </xsl:for-each>
  <!--reconstitute the attributes-->
  <xsl:for-each select="@*">
    <xsl:value-of select="concat(' ',name(.),'=&#x22;')"/>
    <xsl:call-template name="do-text"/>
    <xsl:text>"</xsl:text>
  </xsl:for-each>
  <xsl:choose>
    <xsl:when test="node()">
      <!--reconstitute the content-->
      <xsl:text>&gt;</xsl:text>
      <xsl:apply-templates select="node()"/>
      <xsl:text>&lt;/</xsl:text>
      <xsl:value-of select="name(.)"/>
      <xsl:text>&gt;</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <!--empty element-->
      <xsl:text>/&gt;</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="comment()">
  <xsl:text>&lt;!--</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>--&gt;</xsl:text>
</xsl:template>

<xsl:template match="processing-instruction()">
  <xsl:text>&lt;?</xsl:text>
  <xsl:value-of select="concat(name(.),' ',.)"/>
  <xsl:text>?&gt;</xsl:text>
</xsl:template>

<xsl:template match="text()" name="do-text">
  <xsl:param name="rest" select="."/>
  <xsl:choose>
    <xsl:when test="contains($rest,'&lt;')">
      <xsl:value-of select="substring-before($rest,'&lt;')"/>
      <xsl:text>&amp;lt;</xsl:text>
      <xsl:call-template name="do-text">
        <xsl:with-param name="rest" select="substring-after($rest,'&lt;')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$rest"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

T:\ftemp>call xslt xml2wiki.xsl xml2wiki.xsl
<[xsl:stylesheet|page 1] xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">


<[xsl:output|page 2] method="text"/>

<[xsl:key|page 3] name="names" match="*" use="name(.)"/>

<[xsl:template|page 4] match="*">
<!--reconstitute the element start tag-->
<[xsl:text|page 5]>&lt;[</xsl:text>
<[xsl:value-of|page 6] select="name(.)"/>|page <[xsl:text|page 5]/>
<!--find the first in document order-->
<[xsl:variable|page 7] name="first" select="key('names',name(.))[1]"/>
<!--determine its ordinal based on the uniqueness of element names-->
<[xsl:value-of|page 6] select="count( ($first/preceding::* | $first/ancestor::*) [generate-id(.)= generate-id(key('names',name(.))[1])]) + 1"/>
<[xsl:text|page 5]>]</xsl:text>
<!--reconstitute the namespaces-->
<[xsl:for-each|page 8] select="namespace::*[not(.=../../namespace::*) and name(.)!='xml']">
<[xsl:value-of|page 6] select="concat(' ','xmlns')"/>
<[xsl:if|page 9] test="name(.)">:<[xsl:value-of|page 6] select="name(.)"/></xsl:if>
<[xsl:value-of|page 6] select="concat('="',.,'"')"/>
</xsl:for-each>
<!--reconstitute the attributes-->
<[xsl:for-each|page 8] select="@*">
<[xsl:value-of|page 6] select="concat(' ',name(.),'="')"/>
<[xsl:call-template|page 10] name="do-text"/>
<[xsl:text|page 5]>"</xsl:text>
</xsl:for-each>
<[xsl:choose|page 11]>
<[xsl:when|page 12] test="node()">
<!--reconstitute the content-->
<[xsl:text|page 5]>></xsl:text>
<[xsl:apply-templates|page 13] select="node()"/>
<[xsl:text|page 5]>&lt;/</xsl:text>
<[xsl:value-of|page 6] select="name(.)"/>
<[xsl:text|page 5]>></xsl:text>
</xsl:when>
<[xsl:otherwise|page 14]>
<!--empty element-->
<[xsl:text|page 5]>/></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>


<[xsl:template|page 4] match="comment()">
  <[xsl:text|page 5]>&lt;!--</xsl:text>
  <[xsl:value-of|page 6] select="."/>
  <[xsl:text|page 5]>--></xsl:text>
</xsl:template>

<[xsl:template|page 4] match="processing-instruction()">
  <[xsl:text|page 5]>&lt;?</xsl:text>
  <[xsl:value-of|page 6] select="concat(name(.),' ',.)"/>
  <[xsl:text|page 5]>?></xsl:text>
</xsl:template>

<[xsl:template|page 4] match="text()" name="do-text">
<[xsl:param|page 15] name="rest" select="."/>
<[xsl:choose|page 11]>
<[xsl:when|page 12] test="contains($rest,'&lt;')">
<[xsl:value-of|page 6] select="substring-before($rest,'&lt;')"/>
<[xsl:text|page 5]>&lt;</xsl:text>
<[xsl:call-template|page 10] name="do-text">
<[xsl:with-param|page 16] name="rest" select="substring-after($rest,'&lt;')"/>
</xsl:call-template>
</xsl:when>
<[xsl:otherwise|page 14]>
<[xsl:value-of|page 6] select="$rest"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>


</xsl:stylesheet>
T:\ftemp>rem



--
Upcoming:  hands-on XSLT, XQuery and XSL-FO Washington DC Nov 2009
Interested in other classes?  http://www.CraneSoftwrights.com/s/i/
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

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.