使用Java中的XSOM解析XSD架构。如何访问元素和复杂类型

时间:2011-10-30 22:34:12

标签: java xml xsd schema xsom

我在Java中使用XSOM进行了很多难以解析的.XSD文件。我有两个.XSD文件,一个定义日历,第二个定义全局类型。我希望能够阅读日历文件并确定:

日历有3个属性

  • 有效的是名为eYN的ENUM
  • Cal是一个字符串
  • 状态是一个名为eSTATUS的ENUM

Calendar.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:gtypes="http://www.btec.com/gtypes"
 elementFormDefault="qualified">
<xs:import namespace="http://www.btec.com/gtypes"
 schemaLocation="gtypes.xsd"/>
<xs:element name="CALENDAR">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Valid" type="eYN" minOccurs="0"/>
      <xs:element name="Cal" minOccurs="0">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="gtypes:STRING">
              <xs:attribute name="IsKey" type="xs:string" fixed="Y"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
      <xs:element name="Status" type="eSTATUS" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:complexType name="eSTATUS">
  <xs:simpleContent>
    <xs:extension base="gtypes:ENUM"/>
  </xs:simpleContent>
</xs:complexType>
<xs:complexType name="eYN">
  <xs:simpleContent>
    <xs:extension base="gtypes:ENUM"/>
  </xs:simpleContent>
</xs:complexType>

gtypes.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://www.btec.com/gtypes"
 elementFormDefault="qualified">
<xs:complexType name="ENUM">
  <xs:simpleContent>
    <xs:extension base="xs:string">
      <xs:attribute name="TYPE" fixed="ENUM"/>
      <xs:attribute name="derived" use="optional"/>
      <xs:attribute name="readonly" use="optional"/>
      <xs:attribute name="required" use="optional"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>
<xs:complexType name="STRING">
  <xs:simpleContent>
    <xs:extension base="xs:string">
      <xs:attribute name="TYPE" use="optional"/>
      <xs:attribute name="derived" use="optional"/>
      <xs:attribute name="readonly" use="optional"/>
      <xs:attribute name="required" use="optional"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>
</xs:schema>

我尝试访问此信息的代码如下。我对Java很新 任何风格批评欢迎。

我真的需要知道

  1. 如何访问复杂类型cal并查看它是一个字符串?
  2. 如何访问Status的定义以查看它是eSTATUS类型的枚举 强调文字
  3. 我已多次尝试通过ComplexType和Elements and Content访问正确的信息。但是,我只是没有得到它,我找不到任何有用的例子。我希望(希望)当你知道如何时,最好的方法(相对)简单。所以,再一次,如果有人能指出我正确的方向,那将是一个很大的帮助。

    xmlfile = "Calendar.xsd"
    XSOMParser parser = new XSOMParser();
    
    parser.parse(new File(xmlfile));
    XSSchemaSet sset = parser.getResult();
    XSSchema s = sset.getSchema(1);
    if (s.getTargetNamespace().equals("")) // this is the ns with all the stuff
           // in
    {
      // try ElementDecls
      Iterator jtr = s.iterateElementDecls();
      while (jtr.hasNext())
      {
        XSElementDecl e = (XSElementDecl) jtr.next();
        System.out.print("got ElementDecls " + e.getName());
        // ok we've got a CALENDAR.. what next?
        // not this anyway
        /*  
         *
         * XSParticle[] particles = e.asElementDecl() for (final XSParticle p :
         * particles) { final XSTerm pterm = p.getTerm(); if
         * (pterm.isElementDecl()) { final XSElementDecl ed =
         * pterm.asElementDecl(); System.out.println(ed.getName()); }
         */
      }
    
      // try all Complex Types in schema
      Iterator<XSComplexType> ctiter = s.iterateComplexTypes();
      while (ctiter.hasNext())
      {
        // this will be a eSTATUS. Lets type and get the extension to 
        // see its a ENUM
        XSComplexType ct = (XSComplexType) ctiter.next();
        String typeName = ct.getName();
        System.out.println(typeName + newline);
    
        // as Content
        XSContentType content = ct.getContentType();
        // now what?
        // as Partacle?
        XSParticle p2 = content.asParticle();
        if (null != p2)
        {
          System.out.print("We got partical thing !" + newline);
          // might would be good if we got here but we never do :-(
        }
    
        // try complex type Element Decs
        List<XSElementDecl> el = ct.getElementDecls();
        for (XSElementDecl ed : el)
        {
          System.out.print("We got ElementDecl !" + ed.getName() + newline);
          // would be good if we got here but we never do :-(
        }
    
        Collection<? extends XSAttributeUse> c = ct.getAttributeUses();
        Iterator<? extends XSAttributeUse> i = c.iterator();
        while (i.hasNext())
        {
          XSAttributeDecl attributeDecl = i.next().getDecl();
          System.out.println("type: " + attributeDecl.getType());
          System.out.println("name:" + attributeDecl.getName());
        }
      }
    }
    

1 个答案:

答案 0 :(得分:7)

经过大量的谷歌搜索后,我想我已经回答了我自己的问题。我提议的解决方案毫无希望地得到了广泛的应用。 主要的问题是XSD有三个名称空间,我错误地看错了。

如果您想在XSOM 中解析XSD,请确保在开始之前了解XSD的结构以及标记的含义 - 这将为您节省大量时间。

我会在下面发布我的版本,因为我确信它可以改进!

一些有用的链接:

http://msdn.microsoft.com/en-us/library/ms187822.aspx

http://it.toolbox.com/blogs/enterprise-web-solutions/parsing-an-xsd-schema-in-java-32565

http://www.w3schools.com/schema/el_simpleContent.asp

package xsom.test

import com.sun.xml.xsom.parser.XSOMParser;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSContentType;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSModelGroup;
import com.sun.xml.xsom.XSParticle;
import com.sun.xml.xsom.XSSchema;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSTerm;

import java.util.Iterator;
import java.io.File;
import java.util.HashMap;

public class mappingGenerator
{
  private HashMap mappings;

  public mappingGenerator()
  {
    mappings = new HashMap();
  }

  public void generate(String xmlfile) throws Exception
  {

    // with help from
    // http://msdn.microsoft.com/en-us/library/ms187822.aspx
    // http://it.toolbox.com/blogs/enterprise-web-solutions/parsing-an-xsd-schema-in-java-32565
    // http://www.w3schools.com/schema/el_simpleContent.asp
    XSOMParser parser = new XSOMParser();

    parser.parse(new File(xmlfile));
    XSSchemaSet sset = parser.getResult();

    // =========================================================
    // types namepace
    XSSchema gtypesSchema = sset.getSchema("http://www.btec.com/gtypes");
    Iterator<XSComplexType> ctiter = gtypesSchema.iterateComplexTypes();
    while (ctiter.hasNext())
    {
      XSComplexType ct = (XSComplexType) ctiter.next();
      String typeName = ct.getName();
      // these are extensions so look at the base type to see what it is
      String baseTypeName = ct.getBaseType().getName();
      System.out.println(typeName + " is a " + baseTypeName);
    }

    // =========================================================
    // global namespace
    XSSchema globalSchema = sset.getSchema("");
    // local definitions of enums are in complex types
    ctiter = globalSchema.iterateComplexTypes();
    while (ctiter.hasNext())
    {
      XSComplexType ct = (XSComplexType) ctiter.next();
      String typeName = ct.getName();
      String baseTypeName = ct.getBaseType().getName();
      System.out.println(typeName + " is a " + baseTypeName);
    }

    // =========================================================
    // the main entity of this file is in the Elements
    // there should only be one!
    if (globalSchema.getElementDecls().size() != 1)
    {
      throw new Exception("Should be only elment type per file.");
    }

    XSElementDecl ed = globalSchema.getElementDecls().values()
        .toArray(new XSElementDecl[0])[0];
    String entityType = ed.getName();
    XSContentType xsContentType = ed.getType().asComplexType().getContentType();
    XSParticle particle = xsContentType.asParticle();
    if (particle != null)
    {

      XSTerm term = particle.getTerm();
      if (term.isModelGroup())
      {
        XSModelGroup xsModelGroup = term.asModelGroup();
        term.asElementDecl();
        XSParticle[] particles = xsModelGroup.getChildren();
        String propertyName = null;
        String propertyType = null;
        XSParticle pp =particles[0];
        for (XSParticle p : particles)
        {
          XSTerm pterm = p.getTerm();
          if (pterm.isElementDecl())
          {            
            propertyName = pterm.asElementDecl().getName();
            if (pterm.asElementDecl().getType().getName() == null)
            {
              propertyType = pterm.asElementDecl().getType().getBaseType().getName();
            }
            else
            {
              propertyType = pterm.asElementDecl().getType().getName();              
            }
            System.out.println(propertyName + " is a " + propertyType);
          }
        }
      }
    }
    return;
  }
}   

这个输出是:

ENUM is a string
STRING is a string
eSTATUS is a ENUM
eYN is a ENUM
Valid is a eYN
Cal is a STRING
Status is a eSTATUS