2015-02-10 35 views
1

是否有任何API以编程方式在java中生成XSD? 我需要从Json-Schema生成XSD,我会阅读Json Schema,并根据我在解析过程中遇到的元素创建适当的XSD元素。 所以如果有任何API可以使用XSD元素,它会帮助我在开发过程中。在java中以编程方式生成XSD

+0

请参阅XSOM和Schemagen。 – lexicore 2015-02-15 16:46:34

+0

@ user2478236您是否已经考虑过JAXB?请参阅http://stackoverflow.com/a/7214065/4595816和http://stackoverflow.com/a/11670962/4595816 – dbank 2015-03-02 23:02:58

+0

@dbank是的我已经考虑过JAXB,但是为了使用它,我们需要事先生成jaxb注释的类这是不可能的,因为json是致命的,具有不同的标签名称 – user2478236 2015-03-06 14:14:28

回答

4

我使用的API,如XSOMXerces XML Schema解析 XSD的,但是他们的API不提供方法以编程方式产生 XSD的。 (我想你可以尝试访问其内部实现以某种方式生成XSD,但这会冒你自己的风险,可能不太合适)。

但是,由于XSD本身就是一个XML文档,所以可以使用像DOM通过JAXP以编程方式创建XSD:

package dbank.so; 

import java.io.File; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.FactoryConfigurationError; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.XMLConstants; 


import org.w3c.dom.Document; 
import org.w3c.dom.Element; 


public class SchemaGenExample { 

    private final static String NS_PREFIX = "xs:"; 

    public static void main(String[] args) { 
     try { 
      DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 

      Document doc = docBuilder.newDocument(); 

      Element schemaRoot = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, NS_PREFIX+"schema"); 
      doc.appendChild(schemaRoot); 

      NameTypeElementMaker elMaker = new NameTypeElementMaker(NS_PREFIX, doc); 

      Element idType = elMaker.createElement("simpleType", "idType"); 
      schemaRoot.appendChild(idType); 
      Element idTypeRestr = elMaker.createElement("restriction"); 
      idTypeRestr.setAttribute("base", NS_PREFIX+"string"); 
      idType.appendChild(idTypeRestr); 
      Element idTypeRestrPattern = elMaker.createElement("pattern"); 
      idTypeRestrPattern.setAttribute("value", "[0-9]{6}"); 
      idTypeRestr.appendChild(idTypeRestrPattern); 

      Element itemType = elMaker.createElement("complexType", "itemType"); 
      schemaRoot.appendChild(itemType); 
      Element sequence = elMaker.createElement("sequence"); 
      itemType.appendChild(sequence); 
      Element itemIdElement = elMaker.createElement("element", "ItemId", "idType"); 
      sequence.appendChild(itemIdElement); 
      Element itemNameElement = elMaker.createElement("element", "ItemName", NS_PREFIX+"string"); 
      sequence.appendChild(itemNameElement);   

      Element itemElement = elMaker.createElement("element", "Item", "itemType"); 
      schemaRoot.appendChild(itemElement); 


      TransformerFactory tFactory = TransformerFactory.newInstance(); 
      Transformer transformer = tFactory.newTransformer(); 
      transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); 
      transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
      DOMSource domSource = new DOMSource(doc); 
      //to create a file use something like this: 
      transformer.transform(domSource, new StreamResult(new File("mySchema.xsd"))); 
      //to print to console use this: 
      transformer.transform(domSource, new StreamResult(System.out)); 
     } 
     catch (FactoryConfigurationError | ParserConfigurationException | TransformerException e) { 
      //handle exception 
      e.printStackTrace(); 
     } 
    } 

    /* 
    * Class with methods to make it more convenient to create Element nodes with 
    * namespace prefixed tagnames and with "name" and "type" attributes. 
    */ 
    private static class NameTypeElementMaker { 
     private String nsPrefix; 
     private Document doc; 

     public NameTypeElementMaker(String nsPrefix, Document doc) { 
      this.nsPrefix = nsPrefix; 
      this.doc = doc; 
     } 

     public Element createElement(String elementName, String nameAttrVal, String typeAttrVal) { 
      Element element = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, nsPrefix+elementName); 
      if(nameAttrVal != null) 
       element.setAttribute("name", nameAttrVal); 
      if(typeAttrVal != null) 
       element.setAttribute("type", typeAttrVal); 
      return element; 
     } 

     public Element createElement(String elementName, String nameAttrVal) { 
      return createElement(elementName, nameAttrVal, null); 
     } 

     public Element createElement(String elementName) { 
      return createElement(elementName, null, null); 
     } 
    } 
} 

这将创建一个mySchema.xsd,看起来像这样:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:simpleType name="idType"> 
     <xs:restriction base="xs:string"> 
      <xs:pattern value="[0-9]{6}"/> 
     </xs:restriction> 
    </xs:simpleType> 
    <xs:complexType name="itemType"> 
     <xs:sequence> 
      <xs:element name="ItemId" type="idType"/> 
      <xs:element name="ItemName" type="xs:string"/> 
     </xs:sequence> 
    </xs:complexType> 
    <xs:element name="Item" type="itemType"/> 
</xs:schema> 

这可能是用于一个XML文件,如:

<?xml version="1.0" encoding="UTF-8"?> 
<Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:noNamespaceSchemaLocation="mySchema.xsd"> 
    <ItemId>123456</ItemId> 
    <ItemName>Foo Bar</ItemName> 
</Item> 

我从来没有使用JSON模式的工作,但我想你解析JSON或通过JSON数据结构进行迭代,你可以理清逻辑做一些像上面的例子。

+0

谢谢我使用了你的方法从json Schema生成XSD,它运行良好。也感谢您的代码示例。 – user2478236 2015-03-17 11:43:50