[xsl] Selecting First Direct Sibling

Subject: [xsl] Selecting First Direct Sibling
From: "Wasiq Shaikh" <wasiq911@xxxxxxxxxxx>
Date: Mon, 20 Aug 2007 13:35:13 -0400
Hello,

I'm having a weird and frustrating problem. I have two XSL files (XPath1.0/Xalan2.7J). Both do the same thing. One (mine) is more robust and has a bit more processing. The other more simplistic and different formatting but with the same goal in mind. That goal is to produce a flat list of elements and its attributes from an XML Schema document.

The objective here is to get the comment block directly after an element and/or attribute declaration.

Example:

<xsd:element name="blah">
<!-- This is a comment about the element blah -->
<xsd:attribute name="someAttribute"/>
<xsd:attribute name="blahAttribute"/>
<!-- This is a comment about the attribute blahAttribute under element blah -->
</xsd:element>


Let's focus on grabbing the comment block under attributes. In the simplistic XSL tranformation we have this:

<xs:stylesheet exclude-result-prefixes="xsd"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
  xmlns:xs="http://www.w3.org/1999/XSL/Transform";
  version="1.0"
  xmlns:xalan="http://xml.apache.org/xslt";>

<xs:output indent="yes" xalan:indent-amount="3"/>

<xs:template match="/">
  <xs:element name="Repository">
     <xs:element name="Elements">
        <xs:apply-templates select="/*/*"/>
     </xs:element>
  </xs:element>
</xs:template>

<xs:template match="xsd:element[@name]">
<xs:element name="{@name}">
<xs:if test="string(@type)">
<xs:attribute name="type">
<xs:value-of select="@type"/>
</xs:attribute>
</xs:if>
<xs:for-each select="*[name()='xsd:simpleType' or name()='xsd:complexType']">
<xs:apply-templates select="*"/>
</xs:for-each>
</xs:element>
</xs:template>


<xs:template match="xsd:attribute">
  <xs:element name="attribute">
     <xs:attribute name="name">
        <xs:value-of select="@name"/>
     </xs:attribute>
     <xs:copy-of select="following-sibling::node()[1][self::comment()]"/>
  </xs:element>
</xs:template>

<xs:template match="xsd:sequence|xsd:choice">
  <xs:apply-templates select="*"/>
</xs:template>

<xs:template match="node()|@*"/>

</xs:stylesheet>

This works great. It grabs the comment block directly after an attribute. If it doesn't exist it doesn't process anything. The output will be this:

<blah>
<attribute name="someAttribute"/>
<attribute name="blahAttribute"/>
<!-- This is a comment about the attribute blahAttribute under element blah -->
</blah>


So, I take this simplistic stylesheet and make it more robust, more descriptive, added a few changes to the format, some more descriptive attributes, process complexTypes and extensions and so forth ... However, the comment grab doesn't work.

------

OHHH ... SOB!!! I figured it out! [40 minutes later] I'll leave the original message I was typing so others will understand the problem.

Apparently, adding/removing this line

<xsl:strip-space elements="xsd:complexType"/>

makes the script work/not work. This doesn't make sense to me .. what does this have to do with processing comments?

W.S

_________________________________________________________________
Share More On Messenger with a Windows Live Space http://spaces.live.com/?mkt=en-ca


Current Thread