Stanimir Stamenkov wrote:
Sun, 31 Aug 2008 19:34:07 +0200, /Eric Lilja/:
public class ParseXMLSchema {
public static void main(String[] args) {
ParseXMLSchema instance = new ParseXMLSchema();
instance.parseXMLSchema(new File("test-1.xsd"));
}
private void parseXMLSchema(final File f) {
parseXMLSchema(f.getAbsolutePath());
}
private void parseXMLSchema(final String schemaFileName) {
[...]
XSModel xsModel = xsLoader.loadURI(schemaFileName);
As you may notice XSModel.loadURI(String) accepts an URI, not a file
path, so what you're doing is basically wrong and you should use:
private void parseXMLSchema(final File f) {
parseXMLSchema(f.toURI().toString());
}
Thanks for spotting this, fixed now.
[...]
The output I get when running is:
Complex element: movies, no attributes, no annotations
Complex element: movie, no attributes, 1 annotation(s)
<xs:annotation foo:bar="baz"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="myns"
xmlns:foo="http://www.foobarbaz.com/foo" >
<xs:documentation>SYNTHETIC_ANNOTATION</xs:documentation>
</xs:annotation>
Simple element: title, 1 annotation(s)
<xs:annotation foo:bar="baz"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="myns"
xmlns:foo="http://www.foobarbaz.com/foo" >
<xs:documentation>SYNTHETIC_ANNOTATION</xs:documentation>
</xs:annotation>
, no annotations
Simple element: releaseYear, no annotations
As you can see, the annotation is reported both for the complex
element movie and the simple element title.
I believe this is just a bug in your example - note the ", no
annotations" line just before the last output line "Simple element:
releaseYear, no annotations". What I was pointing previously is the
difference between:
Yeah, it was a silly bug in my example. I had a for loop writing out the
annotations in completely the wrong place, it now works as expected and
as I need it to! I've been able to upgrade the xerces version used in
the software I'm working on!
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:foo="http://www.foobar.com/foo">
<xs:element name="movies">
<xs:complexType>
<xs:sequence>
<xs:element name="movie" type="xs:string"
foo:bar="somevalue"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element/>
</xs:schema>
and:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:foo="http://www.foobar.com/foo">
<xs:element name="movies">
<xs:complexType>
<xs:sequence>
<xs:element ref="movie" foo:bar="somevalue"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="movie" type="xs:string"/>
</xs:schema>
In the first case you get the same annotations for the "movie" element
particle and its element declaration, while in the second you just get
it for the particle.
Also, it seems a bit difficult to parse the annotation string properly
so I can discard annotations I am not interested in.
I've previously used to write the content of the annotations to a DOM
Element (or DocumentFragment), then use the DOM methods to traverse and
extract what I recognize as significant for my application:
Document doc;
...
Node getAnnotation(XSAnnotation annotation) {
DocumentFragment fragment = doc.createDocumentFragment();
annotation.writeAnnotation(fragment,
XSAnnotation.W3C_DOM_ELEMENT);
return fragment;
}
Thanks for this snippet, I used it and came up with this solution which
works for now but needs improving upon:
static public List<String[]> getAnnotationAttrs(final XSObjectList
annotations) {
final List<String[]> annotationList = new ArrayList<String[]>();
if (annotations == null || annotations.getLength() == 0) {
return annotationList;
}
if (annotations.getLength() > 1) {
System.err.println("Handle case where we have more than one
annotation!");
}
final XSAnnotation annotation = (XSAnnotation)annotations.item(0);
Document doc = new DocumentImpl();
DocumentFragment fragment = doc.createDocumentFragment();
annotation.writeAnnotation(fragment, XSAnnotation.W3C_DOM_ELEMENT);
NamedNodeMap attributeMap = fragment.getFirstChild().getAttributes();
Node n1 = attributeMap.getNamedItem("xmlns:foo");
if (n1 == null) {
return annotationList;
}
String[] annotationStrings = new String[]{"foobar", "bar", "baz",
"etc", "etcetc", "etcetcetc"};
for (String str : annotationStrings) {
String[] arr = lookFor(str, attributeMap);
if (arr != null && arr.length == 3) {
annotationList.add(arr);
}
}
return annotationList;
}
static public String[] lookFor(final String lookFor, final NamedNodeMap
attributeMap) {
Node node = attributeMap.getNamedItem("foo:" + lookFor);
if (node == null) {
return null;
}
String[] arr = new String[3];
arr[0] = Constants.GLOADERNAMESPACE;
arr[1] = node.getLocalName();
arr[2] = node.getNodeValue();
return arr;
}
The problem with this code is that it fails to spot invalid annotations
(those not found in the array annotationsStrings). Ideally, I would like
this code to return all annotations beginning with foo: (and their
values) that can be found and then I can check if there are any
unrecognised ones. Any tips on how do that? I'm not experienced with
these libraries.
- Eric (WP)
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]