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

Re: pretty-printing XML into HTML

Subject: Re: pretty-printing XML into HTML
From: "Lars Huttar" <lars_huttar@xxxxxxx>
Date: Thu, 18 Dec 2003 17:43:33 -0600
axis pretty print
Dimitre,
Thanks for your responses re: XPV.
Bug fixes to this are not urgent for me; I have a solution that
works. So don't feel pressured to make bug fixes for my sake.

> >   Thank you for finding the bug(s) related to displaying of
> namespace
> > definitions by the XPV for Mozilla. The fix will be part of the next
> > release.
>
> I just checked and it is clear that the handling of
> namespaces is not a bug,
> but was really forced by the fact that the XPath engine used
> by Mozilla did
> not support the "namespace" axis at all.

Ah. I wasn't aware of that shortcoming in Mozilla. :-S

However there are ways to correct the incorrect output (in this
case at least), even without use of the "namespace"
axis. (There may not be an easy way to do more elegant placement
of namespace declarations, but that's not a big deal.)
Specifically, the findNamespace template should not only
check whether the current element's namespace prefix and uri
have been declared the same way on the nearest ancestor [hmm,
nearest... is that another bug?*], but also whether the current element's
attributes' namespace prefixes and ns-uris have been declared
the same way on the nearest ancestor.

E.g. replace the findNamespace and findAncNamespace templates
with the following:

  <!-- generate namespace declarations as needed for current
	element node and its attributes. -->
  <xsl:template name="findNamespace">
    <xsl:variable name="curnode" select="." />

    <xsl:for-each select=".|@*">
      <xsl:variable name="vName" select="substring-before(name(), ':')"/>
      <xsl:variable name="vUri" select="namespace-uri(.)"/>

      <xsl:variable name="vAncestNamespace">
        <xsl:call-template name="findAncNamespace">
          <xsl:with-param name="pName" select="$vName"/>
          <xsl:with-param name="pUri" select="$vUri"/>
          <xsl:with-param name="pNode" select="$curnode" />
        </xsl:call-template>
      </xsl:variable>

      <xsl:if test="not(number($vAncestNamespace))">
        <!-- not sure if "parent::*" should be "$curnode/parent::*" -->
        <xsl:if test="parent::* or namespace-uri() or contains(name(), ':')">
          <xsl:text> </xsl:text>
          <span class="namespace">
            <xsl:value-of select="'xmlns'"/>
            <xsl:if test="contains(name(), ':')">
              <xsl:value-of select="concat(':', $vName)"/>
            </xsl:if>
          </span>
          <span class="markup">="</span>
          <span class="namespace">
            <xsl:value-of select="namespace-uri()"/>
          </span>
          <span class="markup">"</span>
        </xsl:if>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

  <!-- Return 1 if an ancestor of pNode, or an attribute thereof, has the same prefix (pName) and
namespace-uri (pUri) as
      the current node. Return 0 otherwise. -->
  <xsl:template name="findAncNamespace">
    <xsl:param name="pNode" select="."/>
    <xsl:param name="pName" select="substring-before(name(), ':')"/>
    <xsl:param name="pUri" select="namespace-uri(.)"/>

     <xsl:choose>
      <xsl:when test="not($pNode/parent::*)">0</xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="not(($pName = substring-before(name($pNode/..), ':')
                                            and $pUri  = namespace-uri($pNode/..))
                          or $pNode/../@*[$pName = substring-before(name(), ':')
                                                      and $pUri = namespace-uri()]
                            )">
            <xsl:call-template name="findAncNamespace">
              <xsl:with-param name="pNode" select="$pNode/.."/>
              <xsl:with-param name="pName" select="$pName"/>
              <xsl:with-param name="pUri" select="$pUri"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>1</xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>

  </xsl:template>

> As it was impossible to have the nodeset of all namespace
> nodes belonging to
> a given element, it was impossible to deal with namespaces as such.
> Therefore, I could only check simple things as if a name had
> a namespace
> prefix or namespace-uri().
>
>
> I agree that if Mozilla's XPath implementation was a fully
> conformant one
> then this would be a bug that should be fixed immediately.
> However, this is
> impossible without the lack of support for the "namespace" axis.

While this particular bug can be fixed, as shown above,
I agree it isn't always possible to declare all needed namespaces.
E.g. if your XML happens to be an XSL stylesheet, and some namespace
declarations are used only by XPath expressions (which are of
course in attribute values rather than in element or attribute names),
I don't think there's any way to figure out what the namespace URI's
should be without the namespace:: axis.

> I have not looked for newer versions of Mozilla -- if and
> when they have
> support for the "namespace" axis, XPV for mozilla will start handling
> namespace nodes correctly for the first time.

FWIW, I just checked Mozilla 1.5 and the namespace axis still
doesn't seem to work.  :-(

Lars

*P.S. There is another bug:
findAncNamespace needs to be fixed so that besides
checking whether any ancestor has prefix $pName and ns-uri
$pUri, it needs to make sure there isn't a closer ancestor that
has prefix $pName and a different ns-uri.

For example, the input XML
  <p1:anc1 xmlns:p1="ns1">
    <p1:anc2 xmlns:p1="ns2">
      <p1:anc3 xmlns:p1="ns1" />
    </p1:anc2>
  </p1:anc1>
gets displayed incorrectly as
- <p1:anc1 xmlns:p1="ns1">
  - <p1:anc2 xmlns:p1="ns2">
      <p1:anc3/>
    </p1:anc2>
  </p1:anc1>

i.e. the anc3 element is in the wrong namespace.

The fixed findAncNamespace:

  <!-- Return 1 if an ancestor of pNode (or an attribute thereof) has the same prefix (pName) and
namespace-uri (pUri) as
      the current node, and there is no closer ancestor (or attribute
	thereof) that has the same prefix but a different namespace-uri. Return 0 otherwise. -->
  <xsl:template name="findAncNamespace">
    <xsl:param name="pNode" select="."/>
    <xsl:param name="pName" select="substring-before(name(), ':')"/>
    <xsl:param name="pUri" select="namespace-uri(.)"/>

     <xsl:choose>
      <xsl:when test="not($pNode/parent::*)">0</xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="($pNode/.. | $pNode/../@*)
                                      [$pName = substring-before(name(), ':') and $pUri =
namespace-uri()]">
            1
          </xsl:when>
          <xsl:when test="($pNode/.. | $pNode/../@*)
                                      [$pName = substring-before(name(), ':')]"> <!-- and $pUri !=
namespace-uri() -->
            0
          </xsl:when>
          <xsl:otherwise>
            <xsl:call-template name="findAncNamespace">
              <xsl:with-param name="pNode" select="$pNode/.."/>
              <xsl:with-param name="pName" select="$pName"/>
              <xsl:with-param name="pUri" select="$pUri"/>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>

  </xsl:template>


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


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.