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

标签 java xml xsd schema xsom

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

日历有 3 个属性

  • 有效的是一个名为 eYN 的 ENUM
  • Cal 是一个字符串
  • Status 是一个名为 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());
    }
  }
}

最佳答案

经过大量谷歌搜索,我想我已经回答了我自己的问题。我提出的解决方案毫无希望地偏离了目标。 主要问题是 XSD 有三个 namespace ,我在错误的 namespace 中寻找错误的东西。

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

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

一些有用的链接:

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

关于java - 在 Java 中使用 XSOM 解析 XSD 架构。如何访问元素和复杂类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7948389/

相关文章:

java - 查找大于 SortedMap 中的第一个值

xml - 如何从 xml 文件中删除非法字符?

xml - 在 xsi :type attribute belong? 中对哪个 XML 命名空间使用非限定名称

c# - XSD 文件,从哪里获取 xmlns 参数?

java - 有效证书上的 JDK 11 SSL 错误(在以前的版本中工作)

java - 如何设置 Activity 一直处于 Activity 状态?

c# - 使用 XML 作为小型 C# 应用程序的数据持久性的好方法是什么?

c# - "Type ' http ://www. w3.org/2000/09/xmldsig# :SignatureType ' is not declared" in XmlDocument. 验证(...)

java - 使用jpa从同一个选择同一个表mariadb的表中删除

java - Android 应用程序在 startActivity() 上崩溃