【问题标题】:Read XSD using org.eclipse.xsd.util.XSDResourceImpl使用 org.eclipse.xsd.util.XSDResourceImpl 读取 XSD
【发布时间】:2016-08-23 20:36:48
【问题描述】:

我使用 org.eclipse.xsd.util.XSDResourceImpl 成功读取了 XSD 架构并处理了所有包含的 XSD 元素、类型、属性等。
但是,当我想处理对导入模式中声明的元素的引用时,我得到null 作为它的类型。 XSDResourceImpl 似乎没有处理导入的模式。 有什么想法吗?

    final XSDResourceImpl rsrc = new XSDResourceImpl(URI.createFileURI(xsdFileWithPath));
    rsrc.load(new HashMap());
    final XSDSchema schema = rsrc.getSchema();
    ...
    if (elem.isElementDeclarationReference()){ //element ref
        elem = elem.getResolvedElementDeclaration();
    }
    XSDTypeDefinition tdef = elem.getType(); //null for element ref

更新:
我使导入的 XSD 无效,但没有例外。这意味着它真的没有被解析。有什么办法可以强制将导入的 XSD 与主要的 XSD 一起加载?

【问题讨论】:

    标签: java xsd


    【解决方案1】:

    自动处理importsincludes 有一个重要技巧。您必须使用ResourceSet 来读取主 XSD 文件。

    import org.eclipse.emf.ecore.resource.Resource;
    import org.eclipse.emf.ecore.resource.ResourceSet;
    import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
    import org.eclipse.xsd.util.XSDResourceFactoryImpl;
    import org.eclipse.xsd.util.XSDResourceImpl;
    import org.eclipse.xsd.XSDSchema;
    
    static ResourceSet resourceSet;
    XSDResourceFactoryImpl rf = new XSDResourceFactoryImpl();
    Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xsd", rf);
    resourceSet = new ResourceSetImpl();
    resourceSet.getLoadOptions().put(XSDResourceImpl.XSD_TRACK_LOCATION, Boolean.TRUE);
    XSDResourceImpl rsrc = (XSDResourceImpl)(resourceSet.getResource(uri, true));
    XSDSchema sch = rsrc.getSchema();
    

    那么在处理一个元素、一个属性或一个模型组之前,你必须使用这个:

    elem = elem.getResolvedElementDeclaration();
    attr = attr.getResolvedAttributeDeclaration();
    grpdef = grpdef.getResolvedModelGroupDefinition();
    

    【讨论】:

      【解决方案2】:

      您可以尝试类似的方法,手动解析类型:

      final XSDResourceImpl rsrc = new XSDResourceImpl(URI.createFileURI(xsdFileWithPath));
      rsrc.load(new HashMap());
      final XSDSchema schema = rsrc.getSchema();
      for (Object content : schema.getContents())
      {
          if (content instanceof XSDImport)
          {
              XSDImport xsdImport = (XSDImport) content;
              xsdImport.resolveTypeDefinition(xsdImport.getNamespace(), "");
          }
      }
      

      【讨论】:

        【解决方案3】:

        你可以看看here。特别是这种方法:

           private static void forceImport(XSDSchemaImpl schema) { 
                if (schema != null) { 
                    for (XSDSchemaContent content: schema.getContents()) { 
                        if (content instanceof XSDImportImpl) { 
                            XSDImportImpl importDirective = (XSDImportImpl)content; 
                            schema.resolveSchema(importDirective.getNamespace()); 
                        } 
                    } 
                } 
            } 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-21
          • 1970-01-01
          相关资源
          最近更新 更多