5

Java で XSOM を使用して .XSD ファイルを解析するのは非常に困難です。2 つの .XSD ファイルがあり、1 つはカレンダーを定義し、もう 1 つはグローバル タイプを定義します。カレンダー ファイルを読み取って、次のことを判断できるようにしたいと考えています。

カレンダーには 3 つのプロパティがあります

  • 有効なのは eYN という ENUM です
  • Cal は文字列です
  • ステータスは eSTATUS と呼ばれる ENUM です

カレンダー.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強調テキスト型の列挙であることを確認するにはどうすればよいですか

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());
    }
  }
}
4

1 に答える 1

8

よくグーグルで調べた後、私は自分の質問に答えたと思います。私の提案した解決策はどうしようもなく的外れでした。主な問題は、XSD に 3 つの名前空間があり、間違ったものを間違った名前で探していたことです。

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
于 2011-11-01T07:58:10.390 に答える