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]

Reply via email to