Re: How to recognise reference to global element when walking Schema structure using Schema Object Model API?
"Anthony B. Coates (Google)" <[email protected]>
| Newsgroups | gmane.text.xml.xmlbeans.user |
|---|---|
| Message-ID | <op.u7gyi5mkfez6wi@ubuntuvm> |
Thanks, I tried this, but I don't think it's quite right. I think it is making some assumptions about the element types, so while it works for the example, I don't think it will work generally. For my purposes, I only needed to determine whether a local element has element substitutions. While this means it is a global element reference, I don't need to know that directly. After some playing around, this is what I found seems to work: * you need the parent SchemaType for your SchemaLocalElement * use SchemaType#getElementProperty, with the name of your SchemaLocalElement as the argument * with the returned SchemaProperty, get the 'acceptedNames', and then test which global elements have these QNames * the matching global elements are the valid substitutions. Cheers, Tony. PS you can see code that implements this, albeit in Scala, in the source code for XML Zebra (http://www.xmlzebra.com/). On Mon, 28 Dec 2009 19:33:11 -0000, Gillen, Paul <[email protected]> wrote: > Never occurred to me to try. I wonder what your use case is? That > having been said, this was kind of fun to dink around with. One of the > things to note is that an element can have a name the same as a global > element so simply comparing the names won't work. I think the following > (a) does what you're asking and (b) works; let me know. > > > > My XSD (Note that "UnusedGlobal" is used both as a name for an > "ExternalType" and for a global element): > > <?xml version="1.0" encoding="UTF-8"?> > > <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" > elementFormDefault="qualified" attributeFormDefault="unqualified"> > > <xs:element name="ATTRTEST"> > > <xs:complexType> > > <xs:sequence> > > <xs:element name="TESTELEM"> > > <xs:complexType> > > <xs:attribute name="DEFATTR" > type="xs:string"/> > > </xs:complexType> > > </xs:element> > > <xs:element ref="Element"/> > > <xs:element name="UnusedGlobal" > type="ExternalType"/> > > </xs:sequence> > > </xs:complexType> > > </xs:element> > > <xs:complexType name="ExternalType"> > > <xs:attribute name="externalTypeAttribute" > type="xs:string" use="required"/> > > </xs:complexType> > > <xs:element name="Element"> > > <xs:complexType> > > <xs:attribute name="elementAttribute" > type="xs:string" use="required"/> > > </xs:complexType> > > </xs:element> > > <xs:element name="UnusedGlobal"> > > <xs:complexType> > > <xs:attribute name="elementAttribute" > type="xs:string" use="required"/> > > </xs:complexType> > > </xs:element> > > </xs:schema> > > > > Test XML: > > <?xml version="1.0" encoding="UTF-8"?> > > <ATTRTEST xsi:noNamespaceSchemaLocation="../xsd/AttrTest.xsd" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> > > <TESTELEM DEFATTR="defined attribute"/> > > <Element elementAttribute="element attribute from global > element"/> > > <UnusedGlobal externalTypeAttribute="attribute from complex > type"/> > > </ATTRTEST> > > > > Program (extended from earlier question; forgive extraneous bits): > > package test; > > > > import java.io.File; > > > > import noNamespace.ATTRTESTDocument; > > > > import org.apache.xmlbeans.QNameSet; > > import org.apache.xmlbeans.SchemaGlobalElement; > > import org.apache.xmlbeans.SchemaProperty; > > import org.apache.xmlbeans.SchemaType; > > import org.apache.xmlbeans.SchemaTypeSystem; > > import org.apache.xmlbeans.XmlObject; > > import org.w3c.dom.Node; > > > > public class Atest > > { > > private static final QNameSet QNS = > QNameSet.forWildcardNamespaceString("##any", "*"); > > private ATTRTESTDocument atd; > > > > public static void main(String[] args) > > throws Exception > > { > > Atest mod = new Atest(); > > mod.go(); > > } > > > > private void go() > > throws Exception > > { > > atd = ATTRTESTDocument.Factory.parse(new > File("xml/AttrTest.xml")); > > > > SchemaTypeSystem docSts = > atd.schemaType().getTypeSystem(); > > SchemaGlobalElement[] docSges = docSts.globalElements(); > > > > System.out.println("These are the global elements - > "+docSges.length); > > for (SchemaGlobalElement docSge:docSges) > > { > > System.out.println("\t"+docSge.getName()); > > } > > System.out.println(""); > > > > showChildAttributes(atd); > > } > > > > private void showChildAttributes(XmlObject xo) > > throws Exception > > { > > boolean parentIsGlobal = isGlobalElement(atd, xo); > > String parentName = xo.getDomNode().getLocalName(); > > System.out.println > > ( > > parentName + > > "(globalElement="+parentIsGlobal+"):" > > ); > > > > XmlObject[] xoAttrs = xo.selectAttributes(QNS); > > > > for (int i = 0; i < xoAttrs.length; i++) > > { > > Node domainNode = xoAttrs[i].getDomNode(); > > String childName = domainNode.getLocalName(); > > String childValue = domainNode.getNodeValue(); > > boolean isInXsd = isAttributeInSchema(xo, childName); > > System.out.println > > ( > > "\t" + > > childName + "=\"" + > > childValue + "\"\n\t" + > > "attribute defined in XSD:" + isInXsd > > ); > > > > } > > > > XmlObject[] xoChildren = xo.selectChildren(QNS); > > if (xoChildren != null) > > { > > for (XmlObject xoChild:xoChildren) > > { > > showChildAttributes(xoChild); > > } > > } > > } > > > > private boolean isAttributeInSchema(XmlObject xo, String name) > > throws Exception > > { > > boolean ret = false; > > SchemaType xoSt = xo.schemaType(); > > SchemaProperty[] xoSps = xoSt.getAttributeProperties(); > > for (SchemaProperty xoSp:xoSps) > > { > > if (xoSp.getName().toString().equals(name)) > > { > > ret = true; > > break; > > } > > } > > return ret; > > } > > > > private boolean isGlobalElement(XmlObject doc, XmlObject xo) > > { > > boolean ret = false; > > SchemaTypeSystem docSts = > doc.schemaType().getTypeSystem(); > > SchemaGlobalElement[] docSges = docSts.globalElements(); > > > > for (SchemaGlobalElement docSge:docSges) > > { > > ret = > docSge.getType().getComponentRef().getComponent().equals(xo.schemaType().getRef().getComponent()); > > if (ret) > > { > > break; > > } > > } > > return ret; > > } > > } > > > > Results (Note the results for "UnusedGlobal" which is a name for type > "ExternalType", not a reference to the global element of the same name): > > These are the global elements - 3 > > UnusedGlobal > > ATTRTEST > > Element > > > > null(globalElement=false): > > ATTRTEST(globalElement=true): > > noNamespaceSchemaLocation="../xsd/AttrTest.xsd" > > attribute defined in XSD:false > > TESTELEM(globalElement=false): > > DEFATTR="defined attribute" > > attribute defined in XSD:true > > Element(globalElement=true): > > elementAttribute="element attribute from global element" > > attribute defined in XSD:true > > UnusedGlobal(globalElement=false): > > externalTypeAttribute="attribute from complex type" > > attribute defined in XSD:true > > > > Paul Gillen > > > > > > -----Original Message----- > From: Anthony B. Coates (Google) [mailto:[email protected]] > Sent: Saturday, December 26, 2009 7:25 AM > To: XMLBeans Users List > Subject: How to recognise reference to global element when walking > Schema structure using Schema Object Model API? > > > > Hi. I'm walking a Schema structure using the Schema Object Model API. > > It's pretty good, I must say, but one thing I can't work out is how, when > > examining the children of a complex type, you can tell which are local > > elements, and which are references to global elements. Can anyone tell > me > > what the trick is? Thanks very much in advance, > > > > Cheers, Tony. > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [email protected] > > For additional commands, e-mail: [email protected] > >