java - Create XSD based on root element -


i have xsd shown below , need extract root elements in xsd , create separate xsd each root element pragmatically in java, there framework of java library can aid me in achieving this.

<?xml version='1.0' encoding='windows-1252'?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns="http://www.example.org" targetnamespace="http://www.example.org" elementformdefault="qualified">    <xsd:complextype name="usaddress">       <xsd:sequence>          <xsd:element name="housenumber" type="xsd:string"/>       </xsd:sequence>    </xsd:complextype>    <xsd:complextype name="ordertype">       <xsd:sequence>          <xsd:element name="orderid" type="xsd:string"/>          <xsd:element name="billto" type="usaddress"/>       </xsd:sequence>    </xsd:complextype>    <xsd:element name="customer">       <xsd:complextype>          <xsd:sequence>             <xsd:element name="customerid" type="xsd:string"/>             <xsd:element name="address" type="usaddress"/>          </xsd:sequence>       </xsd:complextype>    </xsd:element>    <xsd:element name="order" type="ordertype"/> </xsd:schema> 

to

<?xml version='1.0' encoding='windows-1252'?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns="http://www.example.org" targetnamespace="http://www.example.org" elementformdefault="qualified">    <xsd:complextype name="usaddress">       <xsd:sequence>          <xsd:element name="housenumber" type="xsd:string"/>       </xsd:sequence>    </xsd:complextype>    <xsd:complextype name="ordertype">       <xsd:sequence>          <xsd:element name="orderid" type="xsd:string"/>          <xsd:element name="billto" type="usaddress"/>       </xsd:sequence>    </xsd:complextype>    <xsd:element name="order" type="ordertype"/> </xsd:schema>  <?xml version='1.0' encoding='windows-1252'?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns="http://www.example.org" targetnamespace="http://www.example.org" elementformdefault="qualified">    <xsd:complextype name="usaddress">       <xsd:sequence>          <xsd:element name="housenumber" type="xsd:string"/>       </xsd:sequence>    </xsd:complextype>    <xsd:element name="customer">       <xsd:complextype>          <xsd:sequence>             <xsd:element name="customerid" type="xsd:string"/>             <xsd:element name="address" type="usaddress"/>          </xsd:sequence>       </xsd:complextype>    </xsd:element> </xsd:schema> 

using xsl 2.0 can have multiple output documents , can define every file name, file content, etc. default java support xsl 2.0 far perfect, use incredible saxon (you can download saxon-he here, unzip , add saxon9he.jar project).

this example xsl 2.0 i've made, works using idea user laune has exposed in his comment. produces 1 output schema every element, , schema not element (types). every new schema contains xs:element's , has xs:include including schema containing types. quite simple (and clever in opinion) method , easy understand if you're familiar xsl (look @ xsl comments).

xsl.xsl

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="2.0">      <xsl:template match="/">         <xsl:for-each select="/*/*[local-name()='element']">             <xsl:variable name="currentelement" select="."/>             <!-- create schema every element containing element, including types schema -->             <xsl:result-document method="xml" href="schema_element_{@name}.xsd">                 <xsl:for-each select="/*[1]">                     <xsl:copy>                         <xsl:copy-of select="@*"/>                         <xsl:element name="include" namespace="http://www.w3.org/2001/xmlschema">                             <xsl:attribute name="schemalocation">schema_types.xsd</xsl:attribute>                         </xsl:element> <!-- include clause -->                         <xsl:copy-of select="$currentelement"/> <!-- content current xs:element -->                     </xsl:copy>                 </xsl:for-each>             </xsl:result-document>         </xsl:for-each>          <xsl:for-each select="/*[1]">             <!-- create types document containing root xs:element's -->             <xsl:result-document method="xml" href="schema_types.xsd">                 <xsl:copy>                     <xsl:copy-of select="@*"/>                     <xsl:copy-of select="node()[local-name()!='element']"/>                 </xsl:copy>             </xsl:result-document>         </xsl:for-each>     </xsl:template>  </xsl:stylesheet> 

the java code needed calling saxon xsl transformation produce output files names dynamically derived in xsl.

main.java

import java.io.file; import javax.xml.transform.transformer; import javax.xml.transform.transformerfactory; import javax.xml.transform.stream.streamresult; import javax.xml.transform.stream.streamsource;  public class main {      public static void main(string[]args) throws exception{         transformerfactory tfactory = transformerfactory.newinstance();         transformer transformer = tfactory.newtransformer(new streamsource(new file("xsl.xsl")));         transformer.transform(new streamsource(new file("schema.xsd")), new streamresult(system.out));     } } 

using example schema, xsl , running java code these files created these filenames (note indentation might lost):

schema_element_customer.xsd

<?xml version="1.0" encoding="utf-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/xmlschema"     xmlns="http://www.example.org" targetnamespace="http://www.example.org"     elementformdefault="qualified">     <include xmlns="http://www.w3.org/2001/xmlschema"         schemalocation="schema_types.xsd" />     <xsd:element name="customer">         <xsd:complextype>             <xsd:sequence>                 <xsd:element name="customerid" type="xsd:string" />                 <xsd:element name="address" type="usaddress" />             </xsd:sequence>         </xsd:complextype>     </xsd:element> </xsd:schema> 

schema_element_order.xsd

<?xml version="1.0" encoding="utf-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/xmlschema"     xmlns="http://www.example.org" targetnamespace="http://www.example.org"     elementformdefault="qualified">     <include xmlns="http://www.w3.org/2001/xmlschema"         schemalocation="schema_types.xsd" />     <xsd:element name="order" type="ordertype" /> </xsd:schema> 

schema_types.xsd

<?xml version="1.0" encoding="utf-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/xmlschema"     xmlns="http://www.example.org" targetnamespace="http://www.example.org"     elementformdefault="qualified">     <xsd:complextype name="usaddress">         <xsd:sequence>             <xsd:element name="housenumber" type="xsd:string" />         </xsd:sequence>     </xsd:complextype>     <xsd:complextype name="ordertype">         <xsd:sequence>             <xsd:element name="orderid" type="xsd:string" />             <xsd:element name="billto" type="usaddress" />         </xsd:sequence>     </xsd:complextype> </xsd:schema> 

update: necessary changes output map

necessary changes output map instead of files in file-system:

based on this answer realized can add setting notified every result-document can writte output want implementing outputuriresolver. i've made 1 writes hashmap:

import java.io.stringwriter; import java.util.map; import javax.xml.transform.result; import javax.xml.transform.transformerexception; import javax.xml.transform.stream.streamresult; import net.sf.saxon.lib.outputuriresolver;  public class hashmapsaveroutputuriresolver implements outputuriresolver{     private map<string, string> results; // save here     public hashmapsaveroutputuriresolver(map<string, string> map){         this.results = map; // set map     }     public outputuriresolver newinstance() {         return this;     }     public result resolve(string href, string base) throws transformerexception { // set resolve file write stringresult wraps stringwritter         stringwriter sw = new stringwriter(); // stringwritter          streamresult sr = new streamresult(sw); // streamresult         sr.setsystemid(href); // id of streamresult = href = filename         return sr;     }     public void close(result result) throws transformerexception { // end of result:document transformed         streamresult sr = (streamresult) result; // streamresult         stringwriter sw = (stringwriter) sr.getwriter(); // streamwritter         string href = sr.getsystemid(); // href (filename)         string content = sw.tostring(); // string file-content         this.results.put(href, content); // save in map     } } 

in main file need add 2 new lines (create map, , set proper setting outputuriresolver associated map).

public static void main(string[] args) throws exception {     hashmap<string, string> results = new hashmap<string, string>(); // map             transformerfactory tfactory = transformerfactory.newinstance();     tfactory.setattribute("http://saxon.sf.net/feature/outputuriresolver", new hashmapsaveroutputuriresolver(results)); // set outputuriresolver     transformer transformer = tfactory.newtransformer(new streamsource(new file("xsl.xsl")));     transformer.transform(new streamsource(new file("schema.xsd")), new streamresult(system.out));     // once transformation has finished map filled } 

Comments

Popular posts from this blog

javascript - Google App Script ContentService downloadAsFile not working -

javascript - IIFE: var vs this - is there any difference? -

r - Grow a ffdf data frame on disk gradually -