XML: Getting "special" attribute

W

WP

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

Stanimir Stamenkov

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
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/
 
W

WP

Hi Staminir and thanks for your reply, see below.

Stanimir said:
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
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)
 
S

Stanimir Stamenkov

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

Stanimir Stamenkov

Sun, 31 Aug 2008 18:11:44 +0200, /WP/:
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.
 
W

WP

Stanimir said:
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)
 
S

Stanimir Stamenkov

Sun, 31 Aug 2008 19:12:30 +0300, /Stanimir Stamenkov/:
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.
 
W

WP

Stanimir said:
Sun, 31 Aug 2008 19:12:30 +0300, /Stanimir Stamenkov/:


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)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top