XML: Getting "special" attribute

Discussion in 'Java' started by WP, Aug 31, 2008.

  1. WP

    WP Guest

    Hello, in my application I need to parse XML Schemas. I'm using Xerces
    to create an XSModel and from a schema and from this XSModel I obtain an
    element declaration map (basically to get the root element from which I
    can get all sub-elements). My problem is that I have XML schemas that
    look like this:

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

    When I inspect the element name I don't see the attribute
    foo:bar="somevalue" among its attributes. Anyone know how to "see" it? I
    can provide a lot more details if needed. Right now my code depends on a
    very old, modified version of xerces that is able to see attributes in
    other namespaces (if that is the correct way to describe the attribute
    foo:bar?).

    - Eric (WP)
    WP, Aug 31, 2008
    #1
    1. Advertising

  2. Sun, 31 Aug 2008 14:54:51 +0200, /WP/:

    > I'm using Xerces
    > to create an XSModel and from a schema and from this XSModel I obtain an
    > element declaration map (basically to get the root element from which I
    > can get all sub-elements).
    >

    [...]
    > <xs:element name="movie" type="xs:string" foo:bar="somevalue"/>

    [...]
    >
    > When I inspect the element name I don't see the attribute
    > foo:bar="somevalue" among its attributes. Anyone know how to "see" it? I
    > can provide a lot more details if needed. Right now my code depends on a
    > very old, modified version of xerces that is able to see attributes in
    > other namespaces (if that is the correct way to describe the attribute
    > foo:bar?).


    I'm not 100% sure whether this is your case but enhancements to the
    XML Schema annotation support was first introduced in Xerces 2.8.0
    <http://xerces.apache.org/xerces2-j/releases.html>:

    > All of the schema component interfaces in the XML Schema API now
    > have a getAnnotations() method which returns a list of
    > XSAnnotations. This includes annotations on particles and attribute
    > uses which were previously "lost".


    If you notice in the original XML Schema specification particle
    components <http://www.w3.org/TR/xmlschema-1/#Particle_details>
    don't have annotations.

    In any case you would get better support on the Xerces-J Users
    mailing list:

    http://mail-archives.apache.org/mod_mbox/xerces-j-users/

    --
    Stanimir
    Stanimir Stamenkov, Aug 31, 2008
    #2
    1. Advertising

  3. WP

    WP Guest

    Hi Staminir and thanks for your reply, see below.

    Stanimir Stamenkov wrote:
    > Sun, 31 Aug 2008 14:54:51 +0200, /WP/:
    >
    >> I'm using Xerces to create an XSModel and from a schema and from this
    >> XSModel I obtain an element declaration map (basically to get the root
    >> element from which I can get all sub-elements).
    >>

    > [...]
    >> <xs:element name="movie" type="xs:string"
    >> foo:bar="somevalue"/>

    > [...]
    >>
    >> When I inspect the element name I don't see the attribute
    >> foo:bar="somevalue" among its attributes. Anyone know how to "see" it?
    >> I can provide a lot more details if needed. Right now my code depends
    >> on a very old, modified version of xerces that is able to see
    >> attributes in other namespaces (if that is the correct way to describe
    >> the attribute foo:bar?).

    >
    > I'm not 100% sure whether this is your case but enhancements to the XML
    > Schema annotation support was first introduced in Xerces 2.8.0
    > <http://xerces.apache.org/xerces2-j/releases.html>:
    >
    >> All of the schema component interfaces in the XML Schema API now have
    >> a getAnnotations() method which returns a list of XSAnnotations. This
    >> includes annotations on particles and attribute uses which were
    >> previously "lost".

    >
    > If you notice in the original XML Schema specification particle
    > components <http://www.w3.org/TR/xmlschema-1/#Particle_details> don't
    > have annotations.


    Thanks for your suggestions. I wrote this complete test program, it uses
    Xerces-J 2.9.1:
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;

    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;

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

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

    Sorry for the length, but I wanted it to be complete. For the following
    test 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="xs:string"
    maxOccurs="unbounded" foo:bar="baz"/>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:schema>

    it produces the following output:
    Complex element: movies, no attributes, no annotations
    Simple element: movie, no annotations

    As you can see, I am unable to detect foo:bar="baz" on the element
    movie. Any ideas what I'm missing in my code?

    >
    > In any case you would get better support on the Xerces-J Users mailing
    > list:
    >
    > http://mail-archives.apache.org/mod_mbox/xerces-j-users/
    >


    I posted there over a week ago without a single reply and activity on
    that list is very low in general so please forgive me. :( But I will
    post their again with the complete example program I used in this post.

    - Eric (WP)
    WP, Aug 31, 2008
    #3
  4. Sun, 31 Aug 2008 18:13:47 +0300, /Stanimir Stamenkov/:
    > Sun, 31 Aug 2008 14:54:51 +0200, /WP/:
    >
    > [...]
    >> <xs:element name="movie" type="xs:string" foo:bar="somevalue"/>

    > [...]
    >>
    >> When I inspect the element name I don't see the attribute
    >> foo:bar="somevalue" among its attributes. Anyone know how to "see" it?
    >> I can provide a lot more details if needed. Right now my code depends
    >> on a very old, modified version of xerces that is able to see
    >> attributes in other namespaces (if that is the correct way to describe
    >> the attribute foo:bar?).

    >
    > I'm not 100% sure whether this is your case but enhancements to the XML
    > Schema annotation support was first introduced in Xerces 2.8.0
    > <http://xerces.apache.org/xerces2-j/releases.html>:


    Lookin at it a bit further and trying it out I think this is more
    what you're after
    <http://xerces.apache.org/xerces2-j/features.html#generate-synthetic-annotations>:

    > Enable generation of synthetic annotations. A synthetic annotation
    > will be generated when a schema component has non-schema attributes
    > but no child annotation.
    >
    > Since: Xerces-J 2.7.0


    Given your original example schema packaged as "example.xsd" with
    the following class, appears to work for me using Xerces 2.9.1 (but
    I guess 2.7.0 should be fine, too):

    -----XSModelTest.java
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.sax.SAXTransformerFactory;
    import javax.xml.transform.sax.TransformerHandler;
    import javax.xml.transform.stream.StreamResult;

    import org.apache.xerces.xs.XSAnnotation;
    import org.apache.xerces.xs.XSComplexTypeDefinition;
    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.XSObjectList;
    import org.apache.xerces.xs.XSParticle;
    import org.w3c.dom.DOMConfiguration;
    import org.w3c.dom.bootstrap.DOMImplementationRegistry;

    public class XSModelTest {

    private static SAXTransformerFactory transformerFactory =
    (SAXTransformerFactory) TransformerFactory.newInstance();

    public static void main(String[] args) throws Exception {
    DOMImplementationRegistry registry =
    DOMImplementationRegistry.newInstance();
    XSImplementation impl = (XSImplementation)
    registry.getDOMImplementation("XS-Loader");
    XSLoader schemaLoader = impl.createXSLoader(null);
    DOMConfiguration config = schemaLoader.getConfig();
    config.setParameter("http://apache.org/xml/features/"
    + "generate-synthetic-annotations",
    Boolean.TRUE);

    XSModel schema = schemaLoader.loadURI(XSModelTest.class
    .getResource("example.xsd").toExternalForm());

    XSElementDeclaration elemDecl =
    schema.getElementDeclaration("movies", null);
    XSComplexTypeDefinition typeDef = (XSComplexTypeDefinition)
    elemDecl.getTypeDefinition();

    XSParticle contentModelParticle = typeDef.getParticle();
    printAnnotations(contentModelParticle.getAnnotations());
    XSModelGroup contentModelGroup = (XSModelGroup)
    contentModelParticle.getTerm();

    XSParticle elemParticle = (XSParticle)
    contentModelGroup.getParticles().item(0);

    System.out.println("--- Particle annotations:");
    printAnnotations(elemParticle.getAnnotations());

    System.out.println("--- Element declaration annotations:");
    elemDecl = (XSElementDeclaration) elemParticle.getTerm();
    printAnnotations(elemDecl.getAnnotations());

    System.out.println("--- End.");
    }

    static void printAnnotations(XSObjectList annotations)
    throws Exception {
    for (int i = 0, len = annotations.getLength();
    i < len; i++) {
    TransformerHandler handler =
    transformerFactory.newTransformerHandler();
    Transformer transformer = handler.getTransformer();
    transformer.setOutputProperty(OutputKeys
    .OMIT_XML_DECLARATION, "yes");
    transformer.setOutputProperty(OutputKeys
    .INDENT, "yes");
    handler.setResult(new StreamResult(System.out));

    ((XSAnnotation) annotations.item(i))
    .writeAnnotation(handler,
    XSAnnotation.SAX_CONTENTHANDLER);
    }
    }

    }
    -----XSModelTest.java--

    --
    Stanimir
    Stanimir Stamenkov, Aug 31, 2008
    #4
  5. Sun, 31 Aug 2008 18:11:44 +0200, /WP/:
    > Stanimir Stamenkov wrote:
    >
    >> In any case you would get better support on the Xerces-J Users mailing
    >> list:
    >>
    >> http://mail-archives.apache.org/mod_mbox/xerces-j-users/

    >
    > I posted there over a week ago without a single reply and activity on
    > that list is very low in general so please forgive me. :( But I will
    > post their again with the complete example program I used in this post.


    Now I see your previous post on the Xerces mailing list. I'm
    subscribed to the list but I'm not following it very closely as I've
    changed job recently and don't work with "hard-core" :) XML
    applications currently. See if my second reply to this thread will
    help.

    --
    Stanimir
    Stanimir Stamenkov, Aug 31, 2008
    #5
  6. WP

    WP Guest

    Stanimir Stamenkov wrote:
    >
    > Now I see your previous post on the Xerces mailing list. I'm subscribed
    > to the list but I'm not following it very closely as I've changed job
    > recently and don't work with "hard-core" :) XML applications
    > currently. See if my second reply to this thread will help.
    >


    Ah! :) And I'm on my first job where I have to work a lot with XML
    schemas. I will try and study the code you posted and, if it works, see
    if I can incorporate into the structure I have (basically what you see
    in the code I posted). Thanks and I will write later today or tomorrow
    by the latest.

    - Eric (WP)
    WP, Aug 31, 2008
    #6
  7. Sun, 31 Aug 2008 19:12:30 +0300, /Stanimir Stamenkov/:

    >>> <xs:element name="movie" type="xs:string" foo:bar="somevalue"/>

    >
    > System.out.println("--- Particle annotations:");
    > printAnnotations(elemParticle.getAnnotations());
    >
    > System.out.println("--- Element declaration annotations:");
    > elemDecl = (XSElementDeclaration) elemParticle.getTerm();
    > printAnnotations(elemDecl.getAnnotations());


    The particle and element declaration components have the same set of
    annotations because in the given case the element declaration is
    local and the defining <xs:element> element represents both the
    particle and the element declaration. With a top level element
    declaration:

    <xs:element name="movie" type="xs:string"/>
    ...
    <xs:element ref="movie" foo:bar="somevalue"/>
    ...

    Only the particle would get the annotation with the 'foo:bar' attribute.

    --
    Stanimir
    Stanimir Stamenkov, Aug 31, 2008
    #7
  8. WP

    WP Guest

    Stanimir Stamenkov wrote:
    > Sun, 31 Aug 2008 19:12:30 +0300, /Stanimir Stamenkov/:
    >
    >>>> <xs:element name="movie" type="xs:string"
    >>>> foo:bar="somevalue"/>

    >>
    >> System.out.println("--- Particle annotations:");
    >> printAnnotations(elemParticle.getAnnotations());
    >>
    >> System.out.println("--- Element declaration annotations:");
    >> elemDecl = (XSElementDeclaration) elemParticle.getTerm();
    >> printAnnotations(elemDecl.getAnnotations());

    >
    > The particle and element declaration components have the same set of
    > annotations because in the given case the element declaration is local
    > and the defining <xs:element> element represents both the particle and
    > the element declaration. With a top level element declaration:
    >
    > <xs:element name="movie" type="xs:string"/>
    > ...
    > <xs:element ref="movie" foo:bar="somevalue"/>
    > ...
    >
    > Only the particle would get the annotation with the 'foo:bar' attribute.
    >


    I'm not quite sure I follow you now but I will study what you said later
    (I'm not even supposed to work today, heh). Anyway, I turned on
    generate-synthetic-annotations as you did in your code and now I get
    annotations. Now I just need to figure out how to extract the
    information I need from them, so I only get those that are important to
    me but that shouldn't be too difficult. Just need to study the
    interfaces a bit. Thanks so much, I really mean it, you have been
    incredibly helpful to me and I appreciate it alot! I wish you the best!
    I will play more with the code tomorrow by the latest and post back on
    how things went. Thanks again!

    - Eric (WP)
    WP, Aug 31, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Passero
    Replies:
    1
    Views:
    1,577
    Craig Deelsnyder
    Mar 3, 2005
  2. Ajay Goel
    Replies:
    1
    Views:
    1,228
    Johannes Koch
    Jul 17, 2003
  3. Bostonasian
    Replies:
    1
    Views:
    803
    Joris Gillis
    Sep 18, 2005
  4. Replies:
    2
    Views:
    1,060
    Henry S. Thompson
    Mar 6, 2006
  5. mahesh
    Replies:
    1
    Views:
    357
    Greg R. Broderick
    Nov 2, 2007
Loading...

Share This Page