Can not parse complexType with complexContent using XSOM Java parser

Hi

I am using this parser: https://xsom.java.net/ To parse and manipulate XML Schema (XSDs).
The original code of the parser tests only two situations of the complexType: simpleContent and complexContent as seen in the source code:
https://java.net/projects/xsom/sources/sources/content/trunk/src/com/sun/xml/xsom/impl/util/SchemaTreeTraverser.java?rev=43
between lines: 0698 to 0813

According to the specification of XML Schema, there are 3 types of content model for complexType: 1) complexType with one complexContent child, 2) complexType with one simpleContent child, and 3) complexType with a group (group, all, choice, and sequence) plus attributes. The last alternative is used to define a complexType without deriving it from other type.

For this reason, I altered the original code (as shown in the snippet code) to include a complexType with group (particle) case.
The problem is when I try to test the complexContent case, it detect it as complexType with group (particle).
For example, I passed the following xsd file:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="item" type="ItemType"/>
  <!--Empty Content Type-->
  <xs:complexType name="ItemType" abstract="true">
    <xs:attribute name="routingNum" type="xs:integer"/>
  </xs:complexType>
  <xs:complexType name="ProductType">
    <xs:complexContent>
      <xs:extension base="ItemType">
        <xs:sequence>
          <xs:element name="number" type="xs:integer"/>
          <xs:element name="name" type="xs:string"/>
          <xs:element name="description"
                       type="xs:string" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="effDate" type="xs:date"/>
        <xs:attribute name="lang" type="xs:language"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

Open in new window


And the result was:
CT with empty content, CT name: ItemType
CT with particle, CT name: ProductType

do I make a mistake in understanding the parser?

The complexType class

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sun.xml.xsom.impl.util;

import com.sun.xml.xsom.XSAttGroupDecl;
import com.sun.xml.xsom.XSAttributeDecl;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSModelGroupDecl;
import com.sun.xml.xsom.XSSchema;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.impl.Const;

/**
 *
 * @author ambaqasah
 */
public class testComplexType {
    public void visit(XSSchemaSet s) {
        for (XSSchema schema : s.getSchemas()) {
            schema(schema);
        }
    }
    public void schema(XSSchema s) {
        // QUICK HACK: don't print the built-in components
        if (s.getTargetNamespace().equals(Const.schemaNamespace)) {
            return;
        }
        for (XSAttGroupDecl attGroupDecl : s.getAttGroupDecls().values()) {
            // parse attGroupDecl(attGroupDecl);
        }
        for (XSAttributeDecl attrDecl : s.getAttributeDecls().values()) {
            // parse attributeDecl(attrDecl);
        }
        for (XSModelGroupDecl modelGroupDecl : s.getModelGroupDecls().values()) {
            // parse modelGroupDecl(modelGroupDecl);
        }
        for (XSElementDecl elementDecl : s.getElementDecls().values()) {
            // parse elementDecl(elementDecl);
        }
        for (XSComplexType complexType : s.getComplexTypes().values()) {
            complexType(complexType);
        }
        for (XSSimpleType simpleType : s.getSimpleTypes().values()) {
            // parse simpleType(simpleType);
        }
    }
    public void complexType(XSComplexType type) {
        if (type.getContentType().asSimpleType() != null) { // simple content
            System.out.println("CT with simpleContent, CT name: " + type.getName());
        }
        else if (type.getContentType().asParticle() != null) {  // particle (group, all, choice, or sequence)
            System.out.println("CT with particle, CT name: " + 
        }
        else {    // complex content
            System.out.println("CT with complexContent, CT name: " + 
        }
    }
}

Open in new window


The test main class

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xsdiff;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.impl.util.testComplexType;
import com.sun.xml.xsom.parser.XSOMParser;
import com.sun.xml.xsom.util.DomAnnotationParserFactory;
import org.xml.sax.SAXException;

/**
 *
 * @author ambaqasah
 */
public class test {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception  {
        String version_name = "C:/complextypeComplexcontentExt01.xsd";
        try {
            XSOMParser reader = new XSOMParser();
            reader.setErrorHandler(new ErrorReporter(System.out));
            reader.setAnnotationParser(new DomAnnotationParserFactory());
            reader.parse(version_name);
            XSSchemaSet xss = reader.getResult();
            if (xss == null) {
                System.out.println("error");
            }
            else {
                testComplexType tCT = new testComplexType();
                tCT.visit(xss);
            }
        }
        catch (SAXException e) {
            if (e.getException() != null) {
                e.getException().printStackTrace();
            }
            else {
                e.printStackTrace();
            }
            throw e;
        }
    }
}

Open in new window

abaqasahAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mccarlIT Business Systems Analyst / Software DeveloperCommented:
Looking at the Javadoc, only .asSimpleType() and .asParticle() methods are provided for XSContentType, so it doesn't look possible to determine all 3 situations from just these 2 methods. I haven't used XSOM before but a quick flick through some further Javadoc leads me to think that XSTerm might have something to help you. Could you try something like the below and see if you get what you are after...
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sun.xml.xsom.impl.util;

import com.sun.xml.xsom.XSAttGroupDecl;
import com.sun.xml.xsom.XSAttributeDecl;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSModelGroupDecl;
import com.sun.xml.xsom.XSSchema;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.impl.Const;

/**
 *
 * @author ambaqasah
 */
public class testComplexType {
    public void visit(XSSchemaSet s) {
        for (XSSchema schema : s.getSchemas()) {
            schema(schema);
        }
    }
    public void schema(XSSchema s) {
        // QUICK HACK: don't print the built-in components
        if (s.getTargetNamespace().equals(Const.schemaNamespace)) {
            return;
        }
        for (XSAttGroupDecl attGroupDecl : s.getAttGroupDecls().values()) {
            // parse attGroupDecl(attGroupDecl);
        }
        for (XSAttributeDecl attrDecl : s.getAttributeDecls().values()) {
            // parse attributeDecl(attrDecl);
        }
        for (XSModelGroupDecl modelGroupDecl : s.getModelGroupDecls().values()) {
            // parse modelGroupDecl(modelGroupDecl);
        }
        for (XSElementDecl elementDecl : s.getElementDecls().values()) {
            // parse elementDecl(elementDecl);
        }
        for (XSComplexType complexType : s.getComplexTypes().values()) {
            complexType(complexType);
        }
        for (XSSimpleType simpleType : s.getSimpleTypes().values()) {
            // parse simpleType(simpleType);
        }
    }
    public void complexType(XSComplexType type) {
        if (type.getContentType().asSimpleType() != null) { // simple content
            System.out.println("CT with simpleContent, CT name: " + type.getName());
        }
        else if (type.getContentType().asParticle() != null) {  // particle (group, all, choice, or sequence)
            XSTerm term = type.getContentType().asParticle().getTerm();

            if (term.isModelGroup()) {
                System.out.println("CT with particle, CT name: " + 
            }
            else {    // complex content
                System.out.println("CT with complexContent, CT name: " + 
            }
        }
    }
}

Open in new window

I'm not sure if .isModelGroup() is definitely the correct .isXXXX() method to use to differentiate between the 2 cases, but try it and see and if not, try some of the other .isXXXX() methods of XSTerm.
0
abaqasahAuthor Commented:
Hi

Thanks for the answer. I tried what you suggest but still not working, it detect it as particle. It seems that there is no support for the complexContent case in this library :(

Regards
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
After looking into this a bit more, it appears that you can't differentiate a complexContent element. This is basically because the parser automatically resolves the extension/restriction specified in the complexContent. Take this as an example...
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:element name="employee" type="fullpersoninfo" />

   <xs:complexType name="personinfo">
      <xs:sequence>
         <xs:element name="firstname" type="xs:string" />
         <xs:element name="lastname" type="xs:string" />
      </xs:sequence>
   </xs:complexType>

   <xs:complexType name="fullpersoninfo">
      <xs:complexContent>
         <xs:extension base="personinfo">
            <xs:sequence>
               <xs:element name="address" type="xs:string" />
               <xs:element name="city" type="xs:string" />
               <xs:element name="country" type="xs:string" />
            </xs:sequence>
         </xs:extension>
      </xs:complexContent>
   </xs:complexType>

   <xs:complexType name="fullpersoninfo2">
      <xs:sequence>
         <xs:sequence>
            <xs:element name="firstname" type="xs:string" />
            <xs:element name="lastname" type="xs:string" />
         </xs:sequence>
         <xs:sequence>
            <xs:element name="address" type="xs:string" />
            <xs:element name="city" type="xs:string" />
            <xs:element name="country" type="xs:string" />
         </xs:sequence>
      </xs:sequence>
   </xs:complexType>
</xs:schema>

Open in new window

In this example, fullPersonInfo and fullPersonInfo2 have the exact same semantic meaning, and so XSOM is resolving fullPersonInfo into the same representation. I guess they have just made the decision that since the two have the same meaning, that there would be no need to differentiate the two. And so I would also say, that if you have such a special case where you need to know between the two, you would just parse the XSD as a standard XML file and get your info from that.
0
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

abaqasahAuthor Commented:
Hi mccarl

Thanks again for the reply. As you guess, I really need to differentiate between the two cases. In my project, I rebuild the schema based on that information. For this reason, I will parse this part as XML document and get what I need. Is it OK to post my trying to this question to make it useful in case someone have the same situation?

Kind regards
0
abaqasahAuthor Commented:
Problem is solved after having a cup of tea :) and relax.

The thing that I miss when I test complexType, is whether it has "anyType" as a base type or not. For this reason line 62 is added. The project should be working fine.
Here is the code:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sun.xml.xsom.impl.util;

import com.sun.xml.xsom.XSAttGroupDecl;
import com.sun.xml.xsom.XSAttributeDecl;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSModelGroupDecl;
import com.sun.xml.xsom.XSSchema;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.XSType;
import com.sun.xml.xsom.impl.Const;

/**
 *
 * @author ambaqasah
 */
public class testComplexType {
    public void visit(XSSchemaSet s) {
        for (XSSchema schema : s.getSchemas()) {
            schema(schema);
        }
    }
    public void schema(XSSchema s) {
        // QUICK HACK: don't print the built-in components
        if (s.getTargetNamespace().equals(Const.schemaNamespace)) {
            return;
        }
        for (XSAttGroupDecl attGroupDecl : s.getAttGroupDecls().values()) {
            // parse attGroupDecl(attGroupDecl);
        }
        for (XSAttributeDecl attrDecl : s.getAttributeDecls().values()) {
            // parse attributeDecl(attrDecl);
        }
        for (XSModelGroupDecl modelGroupDecl : s.getModelGroupDecls().values()) {
            // parse modelGroupDecl(modelGroupDecl);
        }
        for (XSElementDecl elementDecl : s.getElementDecls().values()) {
            // parse elementDecl(elementDecl);
        }
        for (XSComplexType complexType : s.getComplexTypes().values()) {
            complexType(complexType);
        }
        for (XSSimpleType simpleType : s.getSimpleTypes().values()) {
            // parse simpleType(simpleType);
        }
    }
    public void complexType(XSComplexType type) {
        if (type.getContentType().asSimpleType() != null) { // simple content
            System.out.println("CT with simpleContent, CT name: " + type.getName());
        }
        else if (type.getContentType().asEmpty() != null) {
            // Empty (only attribute children)
            System.out.println("CT with empty content, CT name: " + type.getName());
        }
        else {  // particle (group, all, choice, or sequence) or complexContent
            // complextype with complexContent must derived from a user-defined base type
            if (type.getBaseType().getName().equals("anyType")) {
                // particle
                System.out.println("CT with complexContent particle, CT name: " + type.getName());
            }
            else {
                // complexContent
                if (type.getDerivationMethod() == XSType.RESTRICTION) {
                    // RESTRICTION
                    System.out.println("CT with complexContent restriction, CT name: " + type.getName());
                }
                else if (type.getDerivationMethod() == XSType.EXTENSION) {
                    // EXTENSION
                    System.out.println("CT with complexContent extension, CT name: " + type.getName());
                }
            }
        }
    }
}

Open in new window



And this is the tested sample:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="item" type="ItemType"/>
  <!--Empty Content Type-->
  <xs:complexType name="ItemType" abstract="true">
    <xs:attribute name="routingNum" type="xs:integer"/>
  </xs:complexType>
  <xs:complexType name="ProductType">
    <xs:complexContent>
      <xs:extension base="ItemType">
        <xs:sequence>
          <xs:element name="number" type="xs:integer"/>
          <xs:element name="name" type="xs:string"/>
          <xs:element name="description"
                       type="xs:string" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="effDate" type="xs:date"/>
        <xs:attribute name="lang" type="xs:language"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

Open in new window


Thanks mccarl, you gave me the clue to the solution.

Regards
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mccarlIT Business Systems Analyst / Software DeveloperCommented:
;) I'm glad that you were able to find a solution!
0
abaqasahAuthor Commented:
After getting the hint from the expert I tried again and solve the problem. My comment contain the code that solve the problem with example.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.