Subject: Re: [xsl] recursive sorting by element name From: "Davis Ford" <davisford@xxxxxxxxx> Date: Thu, 29 Nov 2007 11:22:20 -0500 |
Hi, a follow-up question... I am running into some issues / inconsistencies running this transformation on command line vs. within java vs. which platform I run it on. I'm hoping the list might have some pointers on how to resolve this. Here is the XSLT (slightly modified from what Ken posted): <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt" > <!-- The xalan param gets back indentation that seems to be broken in the java api --> <xsl:output method="xml" indent="yes" encoding="UTF-8" xalan:indent-amount="4"/> <xsl:strip-space elements="*" /> <xsl:template match="/"> <xsl:apply-templates /> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"> <xsl:sort select="@typeName"/> <xsl:sort select="name(.)"/> <xsl:sort /> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet> When I run this on Ubuntu Linux 7.10 (fully updated) using xsltproc, I encounter this bug: https://bugs.launchpad.net/ubuntu/+source/libxml2/+bug/147144 Namely, it reports the error: runtime error: file SortCollections.xsl line 40 element copy Attribute nodes must be added before any child nodes to an element. When I run this on Mac OS X 1.5 (Leopard -- fully updated) using xsltproc, it does exactly what I want with no problems. When I run this script from Java 1.6 (using JAXB) with the code below, the identity transform does not copy all the attributes over. I end up with missing attributes, and I have no idea why. This behavior with Java is seen on both Windows XP platform and Ubuntu Linux. We want to call the script from java -- since it is being used with JAXB to serialize/de-serialize a collection, and then we use the XSLT to sort it and do an XML-diff in unit tests to detect changes. Does anyone have any workaround or solution to getting a consistent solution ?? Thanks in advance! I have also posted below a sample XML input file that causes this behavior. --JAVA SNIPPET-- import javax.xml.bind.Marshaller; import javax.xml.bind.JAXBSource; import javax.xml.bind.JAXBContext; import javax.xml.transform.Transformer; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; Object object; // the object to be marshalled to XML OutputStream output; // the output stream final Marshaller marshaller = getContext().createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); final JAXBSource source = new JAXBSource(marshaller, object); final StreamResult result = new StreamResult(output); // run XSLT script final StreamSource stylesource = new StreamSource(XmlReaderWriter.class.getResourceAsStream(XSLT)); final Transformer transformer = TransformFactory.newInstance().newTransformer(stylesource); transformer.transform(source, result); --END JAVA SNIPPET-- <?xml version="1.0" encoding="UTF-8"?> <DictionaryModel> <DictionaryModelDescriptor about="modelName1/modelVersion1"> <modelName>modelName1</modelName> <modelVersion>modelVersion1</modelVersion> </DictionaryModelDescriptor> <DictionaryParts> <DictionaryPart abstract="false" typeName="part.full1"> <children/> <parents/> <DictionaryProperties/> <feature>feature.empty3</feature> <maxCardinality>2</maxCardinality> <minCardinality>1</minCardinality> <parentComposition>feature.empty2</parentComposition> <role>role</role> <sequence>1</sequence> </DictionaryPart> <DictionaryPart abstract="false" typeName="part.full5"> <children/> <parents/> <DictionaryProperties/> <feature>feature.empty13</feature> <maxCardinality>2</maxCardinality> <minCardinality>1</minCardinality> <parentComposition>feature.empty12</parentComposition> <role>role</role> <sequence>1</sequence> </DictionaryPart> </DictionaryParts> <DictionaryAssociations> <DictionaryAssociation abstract="false" typeName="association.empty1"> <children/> <parents/> <DictionaryProperties/> </DictionaryAssociation> <DictionaryAssociation compositionType="BIDIRECTIONAL_ASSOCIATION" abstract="false" typeName="association.full2"> <children/> <parents/> <DictionaryProperties> <DictionaryProperty>simple.property.empty4</DictionaryProperty> <DictionaryProperty>composite.property.empty4</DictionaryProperty> </DictionaryProperties> <sourcePart>part.full2</sourcePart> <targetPart>part.full3</targetPart> <resolverStrategy>resolver.strategy</resolverStrategy> </DictionaryAssociation> </DictionaryAssociations> <DictionaryFeatures> <DictionaryFeature composite="false" abstract="false" typeName="feature.empty1"> <children/> <parents/> <DictionaryProperties/> <associations/> <parentComposites/> <parts/> </DictionaryFeature> <DictionaryFeature composite="true" compositionType="SEQUENCE" abstract="true" typeName="feature.full8"> <children> <child>feature.empty9</child> </children> <parents/> <DictionaryProperties> <DictionaryProperty>composite.property.empty5</DictionaryProperty> <DictionaryProperty>simple.property.empty5</DictionaryProperty> </DictionaryProperties> <associations> <association>association.empty3</association> <association>association.empty4</association> </associations> <parentComposites> <parentComposite>feature.empty10</parentComposite> </parentComposites> <parts> <part>part.empty4</part> </parts> <code>code</code> </DictionaryFeature> </DictionaryFeatures> <DictionaryPropertyNodes> <DictionaryPropertyNode abstract="false" typeName="property.node.empty1"> <children/> <parents/> <DictionaryProperties/> </DictionaryPropertyNode> <DictionaryPropertyNode abstract="false" typeName="property.node.full3"> <children> <child>property.node.empty4</child> </children> <parents> <parent>property.node.empty5</parent> </parents> <DictionaryProperties> <DictionaryProperty>composite.property.empty11</DictionaryProperty> <DictionaryProperty>simple.property.empty8</DictionaryProperty> </DictionaryProperties> </DictionaryPropertyNode> </DictionaryPropertyNodes> <DictionaryProperties> <DictionaryProperty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CompositeDictionaryProperty" propertyType="COMPOSITE_ROOT" inherited="false" typeName="composite.property.empty1"> <maxCardinality>2147483647</maxCardinality> <minCardinality>-2147483648</minCardinality> <children/> </DictionaryProperty> <DictionaryProperty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CompositeDictionaryProperty" propertyType="COMPOSITE_ROOT" inherited="false" typeName="composite.property.empty2"> <maxCardinality>2147483647</maxCardinality> <minCardinality>-2147483648</minCardinality> <children/> </DictionaryProperty> <DictionaryProperty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CompositeDictionaryProperty" propertyType="COMPOSITE_ROOT" inherited="false" typeName="composite.property.empty3"> <maxCardinality>2147483647</maxCardinality> <minCardinality>-2147483648</minCardinality> <children/> </DictionaryProperty> <DictionaryProperty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CompositeDictionaryProperty" propertyType="COMPOSITE_CHILD" inherited="true" typeName="composite.property.full6"> <code>code</code> <maxCardinality>3</maxCardinality> <minCardinality>2</minCardinality> <parentObject>feature.empty14</parentObject> <parentProperty>composite.property.empty8</parentProperty> <rootProperty>composite.property.empty7</rootProperty> <children> <child>simple.property.empty6</child> </children> <propertyNode>property.node.empty2</propertyNode> </DictionaryProperty> <DictionaryProperty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SimpleDictionaryProperty" propertyType="SIMPLE_ROOT" inherited="false" typeName="simple.property.empty1"> <maxCardinality>2147483647</maxCardinality> <minCardinality>-2147483648</minCardinality> </DictionaryProperty> <DictionaryProperty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SimpleDictionaryProperty" propertyType="SIMPLE_ROOT" inherited="false" typeName="simple.property.empty2"> <maxCardinality>2147483647</maxCardinality> <minCardinality>-2147483648</minCardinality> </DictionaryProperty> <DictionaryProperty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SimpleDictionaryProperty" propertyType="SIMPLE_ROOT" inherited="false" typeName="simple.property.empty3"> <maxCardinality>2147483647</maxCardinality> <minCardinality>-2147483648</minCardinality> </DictionaryProperty> <DictionaryProperty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SimpleDictionaryProperty" propertyType="SIMPLE_CHILD" inherited="true" typeName="simple.property.full7"> <code>code</code> <maxCardinality>2</maxCardinality> <minCardinality>1</minCardinality> <parentObject>feature.empty16</parentObject> <parentProperty>composite.property.empty9</parentProperty> <rootProperty>composite.property.empty10</rootProperty> <defaultValue>default-value</defaultValue> <dictionaryFeatureRange>feature.range2</dictionaryFeatureRange> <referentFeature>feature.empty17</referentFeature> <dictionaryValueRange>value.range1</dictionaryValueRange> <valueTypeName>value-type-name</valueTypeName> </DictionaryProperty> </DictionaryProperties> <DictionaryFeatureRanges> <DictionaryFeatureRange typeName="feature.range1"> <DictionaryFeatures> <DictionaryFeature>feature.empty11</DictionaryFeature> </DictionaryFeatures> </DictionaryFeatureRange> </DictionaryFeatureRanges> <DictionaryValueRanges> <DictionaryValueRange typeName="value.range2"> <DictionaryRangeItems> <DictionaryRangeItem>range.item3</DictionaryRangeItem> </DictionaryRangeItems> <valueTypeName>value-type-name</valueTypeName> </DictionaryValueRange> </DictionaryValueRanges> <DictionaryRangeItems> <DictionaryRangeItem typeName="range.item2"> <value>4</value> </DictionaryRangeItem> </DictionaryRangeItems> <DictionaryValueTypeNames> <DictionaryValueTypeName>a value type name</DictionaryValueTypeName> <DictionaryValueTypeName>value-type-name</DictionaryValueTypeName> </DictionaryValueTypeNames> </DictionaryModel> On Nov 28, 2007 5:46 PM, G. Ken Holman <gkholman@xxxxxxxxxxxxxxxxxxxx> wrote: > At 2007-11-28 17:04 -0500, Davis Ford wrote: > >Hi, consider the following example: > >... > >I want to sort it as such > >... > >I am trying to come up with a generic XSLT solution that does not use > >explicit element names, but only uses the sort select="name()", and it > >should be recursive such that if say, element <A1> contained further > >elements, then they would also be sorted by element name. > > > >Finally, if the element names are the same, then it should sort them > >by an attribute called "typeName". > > > >Can anyone provide some help? Thank you in advance! > > Am I missing something? This is a variant of a one-template identity > transform. > > I hope the example below helps. > > . . . . . . . . . . Ken > > t:\ftemp>type davis.xml > <Collection> > <CollectionB> > <B2></B2> > <A2></A2> > <A1></A1> > <B1 typeName="2"></B1> > <B1 typeName="1"></B1> > </CollectionB> > <CollectionA> > <B2></B2> > <A2></A2> > <A1></A1> > <B1></B1> > </CollectionA> > </Collection> > > t:\ftemp>type davis.xsl > <?xml version="1.0" encoding="US-ASCII"?> > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > version="1.0"> > > <xsl:output indent="yes"/> > <xsl:strip-space elements="*"/> > > <xsl:template match="@*|node()"> > <xsl:copy> > <xsl:apply-templates select="@*|node()"> > <xsl:sort select="name(.)"/> > <xsl:sort select="@typeName"/> > </xsl:apply-templates> > </xsl:copy> > </xsl:template> > > </xsl:stylesheet> > t:\ftemp>xslt davis.xml davis.xsl con > <?xml version="1.0" encoding="utf-8"?> > <Collection> > <CollectionA> > <A1/> > <A2/> > <B1/> > <B2/> > </CollectionA> > <CollectionB> > <A1/> > <A2/> > <B1 typeName="1"/> > <B1 typeName="2"/> > <B2/> > </CollectionB> > </Collection> > t:\ftemp> > > > > > -- > Comprehensive in-depth XSLT2/XSL-FO1.1 classes: Austin TX,Jan-2008 > World-wide corporate, govt. & user group XML, XSL and UBL training > RSS feeds: publicly-available developer resources and training > G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx > Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ > Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995) > Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc > Legal business disclaimers: http://www.CraneSoftwrights.com/legal
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] recursive sorting by elem, Davis Ford | Thread | Re: [xsl] recursive sorting by elem, Wendell Piez |
[xsl] Help with staregies for outpu, Adam Lipscombe | Date | RE: [xsl] Help with staregies for o, Michael Kay |
Month |