XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
Barry DeBruinSubject: Pulling Elements While Keeping the Parentage
Author: Barry DeBruin
Date: 07 Dec 2006 07:00 PM
The problem:
I have a schema as input and need to remove the majority of the elements and attributes.

The Reason:
I'm working with a product that has a propritary way of defining flat files as well as XML files, so to get a valid schema for XML files this process is needed.

The XSLT Engine:
Originally, I was using Instant Saxon, but had to go with nxslt2.exe for reasons out of my control.

The Current Methodology:
Repeating the process of "descendant::xs:element[@xml='yes'][1]" to
find the first descendant node we need and then using "following-sibling::xs:element[@xml='yes']" to find it's siblings seems to be the only way, but it's by shear brute force and it terribly inelegant.

Example Files:
Input.xsd, Remove_nonXML_1.xsl, and Remove_nonXML_2.xsl are the input and the ugly direction I'm headed in with my XSLT.


Unknownfiles(1).zip
Thanks for any help...

Postnext
James DurningSubject: Pulling Elements While Keeping the Parentage
Author: James Durning
Date: 08 Dec 2006 11:06 AM
1. Instead of rewriting your schema element,
<xs:schema targetNamespace="http://partner2learn.com/MigrationPack/Structure" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://partner2learn.com/MigrationPack/Structure"
.../>
if it is not going to change, for cleanliness you could use
<xsl:copy>
<xsl:copy-of select="@*"/>
...
</xsl:copy>

2. Use templates and apply-templates.
eg. instead of
<xsl:for-each select="xs:element[@xml='yes']">
Use something like
<xsl:apply-templates select="xs:element[@xml='yes']"/>
and have a template
<xsl:template match="xs:element"> ...


3. Simplification example: A lot of the simplification depends on knowing the outerlying structure of the schema. If an element has child nodes, the structure is like:
<xs:element>
<xs:complexType>
<xs:group|all|sequence|choice>
<xs:element>
So we can reduce something like:
<xsl:for-each select="descendant::xs:element[@att='yes'][1]">
<xsl:if test="substring-before(substring-after(@name,'_'),'_')=$d1s0">
<xs:attribute name="{substring-before(@name,'_')}"/>
<xsl:for-each select="following-sibling::xs:element[@att='yes']">
<xs:attribute name="{substring-before(@name,'_')}"/>
</xsl:for-each>
</xsl:if>
</xsl:for-each>

to: (note this assumes you are not skipping levels between nodes with @att='yes')
<xsl:if test="substring-before(substring-after(xs:complexType/*/xs:element[@att='yes'][1]/@name,'_'),'_')=$d1s0">
<xsl:for-each select="xs:complexType/*/xs:element[@att='yes']">
<xs:attribute name="{substring-before(@name,'_')}"/>
</xsl:for-each>
</xsl:if>

Ultimately, it's hard to suggest more without more background information.

Postnext
Barry DeBruinSubject: Pulling Elements While Keeping the Parentage
Author: Barry DeBruin
Date: 09 Dec 2006 10:18 PM
Jame,

Thanks for the copy attributes... much cleaner.

Will a template work in the scenario below:

<xsl:for-each select="descendant::xs:element[@xml='yes'][1]">
<xs:element name="{substring-before(@name,'_Element')}">
<xsl:for-each select="descendant::xs:element[@xml='yes'][1]">
<xs:element name="{substring-before(@name,'_Element')}">
<xsl:for-each select="descendant::xs:element[@xml='yes'][1]">
<xs:element name="{substring-before(@name,'_Element')}">
<xsl:for-each select="descendant::xs:element[@xml='yes'][1]">
<xs:element name="{substring-before(@name,'_Element')}">
<xsl:for-each select="descendant::xs:element[@xml='yes'][1]">
<xs:element name="{substring-before(@name,'_Element')}">
</xs:element>
<xsl:for-each select="following-sibling::xs:element[@xml='yes']">
<xs:element name="{substring-before(@name,'_Element')}"></xs:element>
</xsl:for-each>
<!--Paste above and below here infinitely-->
</xsl:for-each>
</xs:element>
<xsl:for-each select="following-sibling::xs:element[@xml='yes']">
<xs:element name="{substring-before(@name,'_Element')}"></xs:element>
</xsl:for-each>
<!-- and here infinitely-->
</xsl:for-each>
</xs:element>
<xsl:for-each select="following-sibling::xs:element[@xml='yes']">
<xs:element name="{substring-before(@name,'_Element')}"></xs:element>
</xsl:for-each>
<!-- and here infinitely-->
</xsl:for-each>
</xs:element>
<xsl:for-each select="following-sibling::xs:element[@xml='yes']">
<xs:element name="{substring-before(@name,'_Element')}"></xs:element>
</xsl:for-each>
<!-- and here infinitely-->
</xsl:for-each>

Postnext
James DurningSubject: Pulling Elements While Keeping the Parentage
Author: James Durning
Date: 10 Dec 2006 07:44 PM
Want to clarify first:
<a>
<b/>
<c>
<d/>
</c>
</a>

Note that d is the child of c, which is not the first child node of a. Also, note that c is the following sibling of b, so c ends up being a child of b in your result. With the way your current for-eaches are set up, you would end up with:
<a>
<b>
<c/>
</b>
</a>

Is this what you want?

Posttop
Barry DeBruinSubject: Pulling Elements While Keeping the Parentage
Author: Barry DeBruin
Date: 13 Dec 2006 11:45 PM
That's correct.

Really the issue is trying to pull only the elements that have the xml attribute set to "yes", but keeping the hierarchy or nesting.

I can pull them all with <xsl:for-each select="xs:element[@xml='yes']">, but would loose the parent/child relationships.

I completed a version that's working, but it was a lot of copy/paste.. there has to be a better way.


Unknown6_Remove_nonXML.xsl

 
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.