2011-10-30 11 views
5

Mam dużo problemów z analizowaniem pliku .XSD za pomocą XSOM w Javie. Mam dwa pliki .XSD jeden definiuje kalendarz, a drugi typy globalne. Chciałbym być w stanie odczytać plik kalendarza i ustalić, że:Parsowanie schematu XSD za pomocą XSOM w Javie. Jak uzyskać dostęp do typów elementów i złożonych

kalendarz posiada 3 właściwości

  • Ważny jest ENUM nazywa eYN
  • Cal jest String
  • Stan jest ENUM nazywa eSTATUS

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> 

Kod z mojej próbie uzyskania dostępu do tych informacji jest poniżej. Jestem całkiem nowym użytkownikiem Javy, więc każdy styl krytyki jest mile widziany.

I naprawdę trzeba wiedzieć

  1. Jak mogę uzyskać dostęp do typu złożonego CAL i zobaczyć, że jest to ciąg?
  2. Jak uzyskać dostęp do definicji statusu, aby zobaczyć, że to wyliczenie typu eSTATUS podkreślić tekst

mam ma kilka próbuje uzyskać dostęp do właściwych informacji poprzez complexType Elements i treści. Jednak po prostu nie rozumiem tego i nie mogę znaleźć żadnych przykładów, które by pomogły. Spodziewam się (mam nadzieję), że najlepsza metoda jest (stosunkowo) prosta, kiedy wiesz jak. Tak więc, jeśli ktoś mógłby wskazać mi właściwy kierunek, byłoby to wielką pomocą.

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

Odpowiedz

6

Cóż, po dużo googlowania, myślę, że odpowiedziałem na własne pytanie. Zaproponowane przeze mnie rozwiązanie było beznadziejnie szerokie. Głównym problemem było to, że XSD ma trzy przestrzenie nazw, a ja szukałem niewłaściwego.

Jeśli chcesz przeanalizować XSD w XSOM , upewnij się, że rozumiesz strukturę XSD i znaczenie znaczników przed uruchomieniem - zaoszczędzi to ci wiele czasu.

Opublikuję swoją wersję poniżej, ponieważ jestem pewien, że można ją poprawić!

Niektóre linki, które były pomocne:

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; 
    } 
} 

Wyjście z tego jest:

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