Element order is mixed up on document creation after calling substitute()
-------------------------------------------------------------------------

         Key: XMLBEANS-228
         URL: http://issues.apache.org/jira/browse/XMLBEANS-228
     Project: XMLBeans
        Type: Bug
  Components: XmlObject  
    Versions: Version 2.1, Version 2    
 Environment: N/A
    Reporter: Andreas Loew
     Fix For: Version 2.1, Version 2


When trying to create XML documents with XMLBeans 2.x using xmlText() or save() 
that use substitution groups, usage of the substitute() method will mix up the 
order of the XML document (the order will remain correct when substitute() will 
not be called).

We have attached a test case (schema XSD, JUnit test) that demonstrates the 
failure and also attached a patch against plain XMLBeans 2.0.0 that shows where 
the problem is and what is needed to fix problem (although currently at the 
cost of a quite severe perfomance penalty, as I am not an expert in XMLBeans 
internals):

For the test case, XMLBeans 2.0.0 as well as the current SVN snapshot both fail 
as they return

<?xml version="1.0" encoding="UTF-8"?>
<Person 
xmlns="urn:www-apache-org:SubstitutionGroup/substitutionGroupInSequence">
  <FirstCommentElement>ThirdElement</FirstCommentElement>
  <FirstName>FirstElement</FirstName>
  <LastName>SecondElement</LastName>
</Person>

instead of

<?xml version="1.0" encoding="UTF-8"?>
<Person 
xmlns="urn:www-apache-org:SubstitutionGroup/substitutionGroupInSequence">
  <FirstName>FirstElement</FirstName>
  <LastName>SecondElement</LastName>
  <FirstCommentElement>ThirdElement</FirstCommentElement>
</Person>

as would be correct (and will be returned after applying the patches provided).

Basically, the main problem is that  XmlObjectBase#getElementEndingDelimiters() 
after having called SchemaProperty#getJavaSetterDelimiter(), does not take into 
account that the QNameSet returned by getJavaSetterDelimiter() does not yet 
include the "alias names" - i.e. possible substitutions - of those elements 
that happen to be heads of substitution groups.

The patch for XmlObjectBase adds the missing substitutions to this QNameSet. 
This will fix the base problem, but so far at the cost of performance: In order 
to simulate a (non-existing) QNameSet iterator on the set of 
JavaSetterDelimiters, we have not been able to find a more intelligent solution 
than to iterate over the complete array of SchemaGlobalElements and check each 
head of a substitution group for inclusion in the QNameSet (using 
QNameSet#contains()). This definitely is suboptimal and should be replaced by 
an optimized implementation done by somebody who is familiar with the internals 
of XMLBeans. (Sorry!)

Unfortunately, while creating the first fix, we ran into a second (small) issue:

The static method QNameSet#forArray() does mistakenly pass null instead of new 
HashSet() to the private constructor, which results in a NullPointerException. 
The second fix (also included in the patch) will fix this problem.

Please get back to me in case you need any additional details.

Thanks & best regards,

Andreas Loew & Patrik Streicher


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to