Link to home
Start Free TrialLog in
Avatar of abaqasah
abaqasah

asked on

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

Avatar of mccarl
mccarl
Flag of Australia image

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.
Avatar of abaqasah
abaqasah

ASKER

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
SOLUTION
Avatar of mccarl
mccarl
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
;) I'm glad that you were able to find a solution!
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.