[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: pretty-printing XML into HTML
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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|