I have an application that uses SAXONHE 9.2.1.1 api files to convert XML data to plain text. My form has text fields for
- XMLInput_FilePath
- XSLT_FilePath
- TextOutput_FilePath
In the case of okButton_Click () of my form, I have the following:
private void okButton_Click(object sender, EventArgs e) { FileStream xsltTransform_FileStream = File.Open(xsltTransform_FilePath.Text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); FileStream xmlInput_FileStream = File.Open(xmlInput_FilePath.Text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); XmlTextReader modelFileXML = new XmlTextReader(xmlInput_FileStream); modelFileXML.XmlResolver = null; Processor processor = new Processor(); XdmNode input = processor.NewDocumentBuilder().Build(modelFileXML); XsltTransformer xsltTransformer = processor.NewXsltCompiler().Compile(xsltTransform_FileStream).Load(); xsltTransformer.InputXmlResolver = null; xsltTransformer.InitialContextNode = input; Serializer serializer = new Serializer(); serializer.SetOutputFile(writeFile); xsltTransformer.Run(serializer); xsltTransform_FileStream.Close(); modelFileStream.Close(); }
In the context of my XMLInput file, there is a link to the data in another XML file - see below:
XML:
<XMLInput_File Name="XMLInput_File"> <Subsystem Name="Subsystem"> <Requirements Name="Requirement_1"> <Rows> <Path Text="XMLInput2_File:/XMLInput2_File/Subsystem_1/Field_1" /> </Rows> <Rows> <Path Text="XMLInput2_File:/XMLInput2_File/Subsystem_1/Field_2" /> </Rows> </Requirements> <Requirements Name="Requirement_2"> <Rows> <Path Text="XMLInput2_File:/XMLInput2_File/Subsystem_1/Field_3" /> </Rows> <Rows> <Path Text="XMLInput2_File:/XMLInput2_File/Subsystem_2/Field_1" /> </Rows> </Requirements> </Subsystem> </XMLInput_File>
The Text attribute is the place where the external path of the XML file is stored. In the above example, the XML file name will be “XMLInput2_File.xml”.
xml2:
<XMLInput2_File Name="XMLInput2_File"> <Subsystem Name="Subsystem_1"> <Fields Name="Field_1"> S1_Field_One </Fields> <Fields Name="Field_2"> S1_Field_Two </Fields> <Fields Name="Field_3"> S1_Field_Three </Fields> </Subsystem> <Subsystem Name="Subsystem_2"> <Fields Name="Field_1"> S2_Field_One </Fields> <Fields Name="Field_2"> S2_Field_Two </Fields> <Fields Name="Field_3"> S2_Field_Three </Fields> </Subsystem> </XMLInput2_File>
XSLT:
<xsl:template match="/"> <xsl:for-each select ="//Rows/Path"> <xsl:variable name ="interfaceData" select ="@Text"/> <xsl:variable name ="_intfModelName" select ="substring-before(@Text,':/')"/> <xsl:variable name ="_intfFileName" select ="concat('../../OtherXMLFiles/',$_intfModelName,'.xml')"/> <xsl:apply-templates select ="document($_intfFileName)/*[@Name=$_intfModelName]/*"> </xsl:apply-templates> </xsl:for-each> </xsl:template>
I am using Microsoft Visual Studion 2008 Professional Edition to test my conversion, and the script described above works just as it should - document () refers to an external file more specifically. However, when I use my C # Winform application and saxon api calls, my output file contains empty data (empty lines).
After several tests and searching on the Internet, I came to the conclusion that the relative path [in my XSLT] does not apply as it should. It seems that saxon api is processing the document () function from the location of the transform.exe file and not the input file (which I would prefer).
I am trying to make more internet requests on this issue, and I am confused about whether the problem is in my XSLT file or in saxon api calls in the okButton_Click () event. Also, I was on the saxon site and documentation for reference, but to no avail.