Following some existing tutorials, I created below perl script to generate XML from xsd.
Script:
#!/opt/perl/bin/perl -w
use warnings;
use strict;
use XML::Compile::Schema;
use XML::LibXML::Reader;
use XML::Compile::Util qw/pack_type/;
my $in_qfn = $ARGV[0];
my $out_qfn = $ARGV[1];
open (OUT, ">$out_qfn") || die "Unable to create output file: $out_qfn\n";
# Generate the hash of xml
my $schema = XML::Compile::Schema->new($in_qfn);
my $type = pack_type 'urn:testsample','Document';
my $data = $schema->template('PERL', $type);
$data =~ s/#.*//g;
$data =~ s/\s*//g;
$data = eval($data);
# Print the xml
my $doc = XML::LibXML::Document->new('1.0','UTF-8');
my $write = $schema->compile(WRITER=>$type);
my $xml = $write->($doc,$data);
$doc->setDocumentElement($xml);
print OUT $doc->toString(1);
Input Schema:
<xs:schema xmlns="urn:testsample" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:testsample" elementFormDefault="qualified">
<xs:element name="Document">
<xs:complexType>
<xs:sequence>
<xs:element ref="address" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="address">
<xs:complexType>
<xs:sequence>
<xs:element name="Pname" type="Pname" minOccurs="0" maxOccurs="1"/>
<xs:element ref="street" minOccurs="0" maxOccurs="3"/>
<xs:element name="contact" type="contacttype"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="contacttype">
<xs:choice>
<xs:element ref="bday" minOccurs="0" maxOccurs="1"/>
<xs:element ref="email" minOccurs="0" maxOccurs="1"/>
<xs:element ref="postal" minOccurs="0" maxOccurs="2"/>
</xs:choice>
</xs:complexType>
<xs:simpleType name="Pname">
<xs:restriction base="xs:string">
<xs:enumeration value="AA"/>
<xs:enumeration value="BB"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="street" type="xs:string"/>
<xs:element name="email" type="xs:string"/>
<xs:element name="postal" type="xs:string"/>
<xs:element name="bday" type="xs:date"/>
</xs:schema>
The output is correct. To take it further, in the example schema, there are choice elements, enumerations and repetitive elements. I would like to:
1. iterate all the possible values
2. generate maximum repetitive elements, if unbounded then 99
3. generate all choice values
4. split them into multiple XML files such that every XML is valid against the original schema.
The output XML files amount is: i*j (i: the amount of choices in each node recursively, can be i1*i2*i3... j: the amount of enumerations in each node recursively, can be j1*j2*j3...)
In this case, it outputs 2*3=6 XML files (if there is an embedded node with 2 enumeration values, then it becomes 2*2*3=12 XML files), similar to:
XML file 1:
<x0:Document xmlns:x0="urn:testsample">
<x0:address>
<x0:Pname>AA</x0:Pname>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:contact>
<x0:email>example</x0:email>
</x0:contact>
</x0:address>
</x0:Document>
XML File 2:
<x0:Document xmlns:x0="urn:testsample">
<x0:address>
<x0:Pname>BB</x0:Pname>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:contact>
<x0:email>example</x0:email>
</x0:contact>
</x0:address>
</x0:Document>
XML File 3:
<x0:Document xmlns:x0="urn:testsample">
<x0:address>
<x0:Pname>AA</x0:Pname>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:contact>
<x0:bday>2017-10-2</x0:bday>
</x0:contact>
</x0:address>
</x0:Document>
XML File 4:
<x0:Document xmlns:x0="urn:testsample">
<x0:address>
<x0:Pname>BB</x0:Pname>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:contact>
<x0:bday>2017-10-2</x0:bday>
</x0:contact>
</x0:address>
</x0:Document>
XML File 5:
<x0:Document xmlns:x0="urn:testsample">
<x0:address>
<x0:Pname>AA</x0:Pname>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:contact>
<x0:postal>example</x0:postal>
<x0:postal>example</x0:postal>
</x0:contact>
</x0:address>
</x0:Document>
XML File 6:
<x0:Document xmlns:x0="urn:testsample">
<x0:address>
<x0:Pname>BB</x0:Pname>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:street>example</x0:street>
<x0:contact>
<x0:postal>example</x0:postal>
<x0:postal>example</x0:postal>
</x0:contact>
</x0:address>
</x0:Document>
I firstly stuck to get the correct value for i and j, as they will be variables used in the generated XML file names, then the possible split. Any help is appreciated!