Stanimir Stamenkov wrote:
Hello Eric,

Thu, 21 Aug 2008 14:03:26 +0200, /Eric Lilja/:

Hello, my first time posting on this list. I've taken over some code that was written several years ago and I'm supposed to update it. One of the things the code does is parse an xml schema. I encountered a problem when I upgraded xerces to 2.9.1: The method XSElementDeclaration.getAnnotationAttrs() is no longer available. I googled for getAnnotationAttrs to see if I could find information on what I should use instead but google returned zero hits, heh.

Let me clarify with an example schema:
<?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:schema>
[...]

If I've got it right in the comp.lang.java.programmer group, you need the "generate-synthetic-annotations" [1] feature available since Xerces 2.7.0. Here's a link to my example in that group, for reference:

http://groups.google.com/group/comp.lang.java.programmer/msg/6d3b9efbd55ad539

[1] http://xerces.apache.org/xerces2-j/features.html#generate-synthetic-annotations


Yes, thank you very much indeed, but I do have a problem which I believe you mentioned in the java-group. Consider this schema:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
    targetNamespace="myns" xmlns="myns"
    elementFormDefault="qualified"
    xmlns:foo="http://www.foobarbaz.com/foo";>
    <xs:element name="movies">
        <xs:complexType>
            <xs:sequence>
<xs:element name="movie" type="movieType" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="movieType">
        <xs:sequence>
<xs:element name="title" type="xs:string" maxOccurs="unbounded" foo:bar="baz"/>
            <xs:element name="releaseYear" type="xs:positiveInteger"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

My test program:
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.xerces.xs.XSAnnotation;
import org.apache.xerces.xs.XSComplexTypeDefinition;
import org.apache.xerces.xs.XSConstants;
import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSImplementation;
import org.apache.xerces.xs.XSLoader;
import org.apache.xerces.xs.XSModel;
import org.apache.xerces.xs.XSModelGroup;
import org.apache.xerces.xs.XSNamedMap;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSParticle;
import org.apache.xerces.xs.XSTerm;
import org.apache.xerces.xs.XSTypeDefinition;

import org.apache.xerces.impl.xs.XSImplementationImpl;
import org.w3c.dom.DOMConfiguration;

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) {

      XSImplementation xsImplementation = new XSImplementationImpl();

XSLoader xsLoader = xsImplementation.createXSLoader(null); // or new XSLoaderImpl();

      DOMConfiguration config = xsLoader.getConfig();


config.setParameter("http://apache.org/xml/features/generate-synthetic-annotations";, Boolean.TRUE);

      XSModel xsModel = xsLoader.loadURI(schemaFileName);

XSNamedMap elementMap = xsModel.getComponents(XSConstants.ELEMENT_DECLARATION);

XSElementDeclaration topElementDecl = (XSElementDeclaration)elementMap.item(0);

      process(topElementDecl);
   }

   private void process(final XSElementDeclaration elementDecl) {
      if (elementDecl == null) {
         System.err.println("elementDecl is null.");

         return;
      }

XSComplexTypeDefinition typeDef = (XSComplexTypeDefinition)elementDecl.getTypeDefinition();

      System.out.print("Complex element: " + elementDecl.getName());

      XSObjectList attributeUsesList = typeDef.getAttributeUses();

      if (attributeUsesList.getLength() == 0) {
         System.out.print(", no attributes");
      }
      else {
         for (int i = 0; i < attributeUsesList.getLength(); ++i) {
System.out.println("Attribute " + i + 1 + ": " + attributeUsesList.item(i).getName());
         }
      }

List<XSElementDeclaration> ces = new ArrayList<XSElementDeclaration>();

XSModelGroup modelGroup = (XSModelGroup)typeDef.getParticle().getTerm();

      XSObjectList particles = modelGroup.getParticles();

      for (int i = 0; i < particles.getLength(); ++i) {
         XSParticle particle = (XSParticle)particles.item(i);
         XSTerm     term     = particle.getTerm();

         XSObjectList annotations = particle.getAnnotations();

         printAnnotations(annotations);

         if (term instanceof XSElementDeclaration) {
            XSElementDeclaration newElement = (XSElementDeclaration)term;

if (newElement.getTypeDefinition().getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
               System.out.print("Simple element: " + newElement.getName());

XSObjectList simpleElementAnnotations = newElement.getAnnotations();

               printAnnotations(simpleElementAnnotations);
            }
else if (newElement.getTypeDefinition().getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
               ces.add(newElement);
            }
            else {
               System.out.println("Other type.");
            }
         }
         else {
            System.out.println("Something else.");
         }
      }

      for (XSElementDeclaration e : ces) {
         process(e);
      }
   }

   private void printAnnotations(final XSObjectList annotations) {
      if (annotations.getLength() == 0) {
         System.out.println(", no annotations");
      }
      else {
System.out.println(", " + annotations.getLength() + " annotation(s)");

         for (int i = 0; i < annotations.getLength(); ++i) {

System.out.println(((XSAnnotation)annotations.item(i)).getAnnotationString());
         }
      }
   }
}

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. This is a problem for me, the old, hacked version of Xerces I'm trying to replace would only report it for the element title. I believe you said something about this in the java group, but it sounds like I can't get the behavior I need. :( Also, it seems a bit difficult to parse the annotation string properly so I can discard annotations I am not interested in.

- Eric (WP)


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

Reply via email to