You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xerces.apache.org by Stanimir Stamenkov <s7...@netscape.net> on 2008/09/01 05:47:38 UTC

Re: Parsing xml schema, what happened to XSElementDeclaration.getAnnotationAttrs()?

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());
    }

[...]
> 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:

<?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;
     }

-- 
Stanimir

---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Parsing xml schema, what happened to XSElementDeclaration.getAnnotationAttrs()?

Posted by Eric Lilja <mi...@gmail.com>.
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: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org