As the title says I have a xml and a xsd file and want to transform them into a csv file using java and structurize it with a xsl file.
At the moment I can only transform my xml file and structurize it with a xsl file with this code in java:
public static void xmlToCSV() throws Exception{
File stylesheet = new File("style.xsl");
File xmlSource = new File("xmlData.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlSource);
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
Source source = new DOMSource(document);
Result outputTarget = new StreamResult(new File("output.csv"));
transformer.transform(source, outputTarget);
}
sytle.xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="Person">
<xsl:value-of select="Name"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="Gender"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="Age"/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
xmlData.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<Person>
<Name>Bob</Name>
<Gender>m</Gender>
<Age>19</Age>
</Person>
</Document>
Output:
Bob,m,19
In my xsd you can see some limitations I want to have in my csv file:
<xs:element maxOccurs="1" minOccurs="1" name="Name">
<xs:element maxOccurs="1" minOccurs="1" name="Gender">
<xs:element maxOccurs="1" minOccurs="0" name="Age">
What I want:
name,min,max,value
Bob,1,1,Name
m,1,1,Gender
19,0,1,Age
I am pretty new to xsl and don't know how to use the xsd and where. I saw something about import the xsd in your xsl file but it didn't work out for me. I hope I didn't forget some important information. Thank you for your help.
Try this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text"/>
<!-- strip-space: so we have not unwanted linefeeds-->
<xsl:strip-space elements="*"/>
<!-- document(the uri to the schema.xsd)-->
<xsl:variable name="schema" select="document('some.xsd')"/>
<xsl:key name="schema-key" match="xs:element" use="@name" />
<xsl:template match="/">
<xsl:text>name,min,max,value</xsl:text>
<xsl:text> </xsl:text>
<xsl:apply-templates select="Document/Person"/>
</xsl:template>
<xsl:template match="Person/*">
<xsl:variable name="elementName" select="name()"/>
<xsl:value-of select="text()"/>
<xsl:text>,</xsl:text>
<!-- To use a key on a external document in xslt 1.0 we have to change the context to that document -->
<xsl:for-each select="$schema">
<xsl:variable name="schemaElement" select="key('schema-key', $elementName)"/>
<xsl:value-of select="$schemaElement/@minOccurs"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="$schemaElement/@maxOccurs"/>
<xsl:text>,</xsl:text>
</xsl:for-each>
<xsl:value-of select="$elementName"/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
will give you the wanted result:
name,min,max,value
Bob,1,1,Name
m,1,1,Gender
19,0,1,Age