在java中以编程方式生成XSD

2024-04-19

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


我使用过 API,例如XSOM https://xsom.java.net/ and Xerces XML 模式 http://xerces.apache.org/xerces2-j/faq-xs.html#faq-11 to parseXSD,但他们的 API 不提供以编程方式进行的方法generateXSD 的。 (我想您可以尝试访问他们的内部实现以某种方式生成 XSD,但这将由您自己承担风险,并且可能是不明智的。)

但是,由于 XSD 本身就是 XML 文档,因此您可以使用类似的内容DOM http://www.w3.org/DOM/通过JAXP http://docs.oracle.com/javase/tutorial/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 Schema,但我想当您解析 JSON 或迭代 JSON 数据结构时,您可以理清逻辑以执行与上面示例类似的操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在java中以编程方式生成XSD 的相关文章

随机推荐