<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><head><META content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
</head><BODY>
<DIV>
<font size="-1">I've put together a test case for this. See attached
files. The XML and XSD files go in junit-test/resources<br>
The TestSAXComplicatedSchema.java goes in
junit-test/src/java/org/jdom/tes/cases/input<br>
<br>
Whatever fix we decide on can be run through this.... currently it
just reproduces the problem.<br>
<br>
The 'bonus' is that the XML/schema/imports are much simpler than
the MODS stuff.<br>
<br>
Thomas, I've looked at your latest patch, and I think it is too
heavy-weight... in the sense that it carries a lot of data through
the hierarchy... two maps, a list, it all seems like too much. I
struggled to follow some of the logic. I think there's a simpler
option.<br>
<br>
I fact, when I looked more closely, the data is all available. If
you encounter an attribute with the same qName and localname, but
with a URI, then hunt up the Element hierarchy for a prefixed
declaration of that namespace.<br>
<br>
This method requires no additional member fields, and I believe it
correctly sets the prefixes.... but, not quite.... there is one
case where it legitimately may not have an available prefix...<br>
<br>
There are conditions where there is no prefix available for a
default/fixed attribute. Specifically, if an attribute is declared
to be form="qualified", and the Default namespace for the document
is the targetNamespace for the attribute.... and, the XML document
does not have an explicitly prefixed version of the default
namespace as well, then there is no way to get the namespace
prefix. Wow, that was a mouthful.<br>
<br>
There has to be some mechanism to create a 'default' or 'computed'
prefix.<br>
<br>
I have run through a lot of different scenarios, and I figure, the
issue can be 'easily' solved with a 'simple' patch. The following
code will reuse the most appropriate prefix, if there is one, and
it will create a prefix in those conditions where there is not one
available. The 'generated' ones will be of the form attns0 through
attns.... and it will keep looking until if finds an unused
prefix.<br>
<br>
As it happens, the necessary code change is very localized in
SAXHandler. Just replace one line!<br>
<br>
This approach localizes any negative (buggy) impacts to just one
'outside' condition, and does not introduce potential bugs in the
broader SAXHandler.<br>
<br>
of course, there's probably something I have overlooked.... any
ideas?<br>
<br>
IN SAXHandler, you can add a new 'else' condition to the
startElement method (replace line 574 with):<br>
<br>
</font><font size="-1"> } else if (atts.getURI(i) != null
&& atts.getURI(i).length() > 0) {<br>
// the localname and qName are the same, but there
is a<br>
// Namspace URI. We need to figure out the
namespace prefix.<br>
// this is an unusual condition. Currently the
only known trigger<br>
// is when there is a fixed/defaulted attribute
from a validating<br>
// XMLSchema, and the attribute is in a different
namespace<br>
// than the rest of the document, this happens
whenever there<br>
// is an attribute definition that has
form="qualified".<br>
// <xs:attribute name="attname"
form="qualified" ... /><br>
// or the schema sets
attributeFormDefault="qualified"<br>
String attURI = atts.getURI(i);<br>
Namespace attNS = null;<br>
Element p = element;<br>
// We need to ensure that a particular prefix has
not been<br>
// overridden at a lower level than what we are
expecting.<br>
// track all prefixes to ensure they are not
changed lower<br>
// down.<br>
HashSet overrides = new HashSet();<br>
uploop: do {<br>
// Search up the Element tree looking for a
prefixed namespace<br>
// matching our attURI<br>
if (p.getNamespace().getURI().equals(attURI)<br>
&&
!overrides.contains(p.getNamespacePrefix())<br>
&&
!"".equals(element.getNamespace().getPrefix())) {<br>
// we need a prefix. It's impossible to
have a namespaced<br>
// attribute if there is no prefix for
that attribute.<br>
attNS = p.getNamespace();<br>
break uploop;<br>
}<br>
overrides.add(p.getNamespacePrefix());<br>
for (Iterator it =
p.getAdditionalNamespaces().iterator(); <br>
it.hasNext(); ) {<br>
Namespace ns = (Namespace)it.next();<br>
if (!overrides.contains(ns.getPrefix())<br>
&&
attURI.equals(ns.getURI())) {<br>
attNS = ns;<br>
break uploop;<br>
}<br>
overrides.add(ns.getPrefix());<br>
}<br>
if (p == element) {<br>
p = currentElement;<br>
} else {<br>
p = p.getParentElement();<br>
}<br>
} while (p != null);<br>
if (attNS == null) {<br>
// we cannot find a 'prevailing' namespace
that has a prefix<br>
// that is for this namespace.<br>
// This basically means that there's an
XMLSchema, for the<br>
// DEFAULT namespace, and there's a
defaulted/fixed<br>
// attribute definition in the XMLSchema
that's targeted<br>
// for this namespace,... but, the user has
either not<br>
// declared a prefixed version of the
namespace, or has<br>
// re-declared the same prefix at a lower
level with a<br>
// different namespace.<br>
// All of these things are possible.<br>
// Create some sort of default prefix.<br>
int cnt = 0;<br>
String base = "attns";<br>
String pfx = base + cnt;<br>
while (overrides.contains(pfx)) {<br>
cnt++;<br>
pfx = base + cnt;<br>
}<br>
attNS = Namespace.getNamespace(pfx, attURI);<br>
}<br>
attribute = factory.attribute(attLocalName,
atts.getValue(i),<br>
attType, attNS);<br>
} else {<br>
<br>
<br>
Rolf<br>
</font><br>
On 07/20/2011 09:23 AM, Thomas Scheffler wrote:
<blockquote cite="mid:4E26D6E5.2010309@uni-jena.de" type="cite">Hi,
<br>
<br>
if I parse a valid MODS document with XML Schema validation, JDOM
changes attributes as it handles default values of schema not
correctly (by ignoring the namespace).
<br>
<br>
Here is a short code to demonstrate this:
<br>
<br>
SAXBuilder builder = new SAXBuilder(true);
<br>
builder.setFeature(<a class="moz-txt-link-rfc2396E" href="http://xml.org/sax/features/namespaces">"http://xml.org/sax/features/namespaces"</a>,
true);
<br>
builder.setFeature(<a class="moz-txt-link-rfc2396E" href="http://xml.org/sax/features/namespace-prefixes">"http://xml.org/sax/features/namespace-prefixes"</a>,
true);
<br>
builder.setFeature(<a class="moz-txt-link-rfc2396E" href="http://apache.org/xml/features/validation/schema">"http://apache.org/xml/features/validation/schema"</a>,
true);
<br>
<br>
Document document = builder.build(new
URL(<a class="moz-txt-link-rfc2396E" href="http://academiccommons.columbia.edu/download/fedora_content/show_pretty/ac:111060/CONTENT/ac111060_description.xml">"http://academiccommons.columbia.edu/download/fedora_content/show_pretty/ac:111060/CONTENT/ac111060_description.xml"</a>));<br>
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
<br>
xout.output(document, System.out);
<br>
<br>
Here is a result fragment:
<br>
<br>
<name type="simple">
<br>
<namePart type="family">Edwards</namePart>
<br>
<namePart type="given">Stephen A.</namePart>
<br>
<role>
<br>
<roleTerm type="text">author</roleTerm>
<br>
</role>
<br>
<affiliation>Columbia University. Computer
Science</affiliation>
<br>
</name>
<br>
<br>
If you look at the original document you can see, that @type of
name is "personal". The "simple" comes from the xlink XML-Schema
that was included by the MODS-Schema. Therefor the result fragment
should look like this:
<br>
<br>
<name type="personal" xlink:type="simple">
<br>
<namePart type="family">Edwards</namePart>
<br>
<namePart type="given">Stephen A.</namePart>
<br>
<role>
<br>
<roleTerm type="text">author</roleTerm>
<br>
</role>
<br>
<affiliation>Columbia University. Computer
Science</affiliation>
<br>
</name>
<br>
<br>
If I use DOM from Java this is done correctly (but a bit ugly as
it does not use the namespace prefix already defined).
<br>
<br>
Could someone just fix this, please?
<br>
<br>
Regards,
<br>
<br>
Thomas Scheffler
<br>
_______________________________________________
<br>
To control your jdom-interest membership:
<br>
<a class="moz-txt-link-freetext" href="http://www.jdom.org/mailman/options/jdom-interest/youraddr@yourhost.com">http://www.jdom.org/mailman/options/jdom-interest/youraddr@yourhost.com</a>
<br>
<br>
</blockquote>
</DIV>
<DIV> </DIV>
<DIV STYLE="FONT-SIZE: 9pt; FONT-FAMILY: Courier New">
<HR>
<DIV ALIGN="justify" STYLE="FONT-SIZE: 9pt; FONT-FAMILY: Courier New"><FONT FACE="Arial" SIZE="1">This email and any files transmitted with it are confidential and proprietary to Algorithmics Incorporated and its affiliates ("Algorithmics"). If received in error, use is prohibited. Please destroy, and notify sender. Sender does not waive confidentiality or privilege. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. Algorithmics does not accept liability for any errors or omissions. Any commitment intended to bind Algorithmics must be reduced to writing and signed by an authorized signatory.</FONT></DIV>
<HR>
<DIV></DIV></DIV></BODY></HTML>