Ho un'applicazione che utilizza i file API di SAXONHE 9.2.1.1 per trasformare i dati XML in testo normale. La mia forma ha le caselle di testo perApp che utilizza saxonHE (9.2.1.1) api per elaborare XSLT (v2.0) su più file XML
- XMLInput_FilePath
- XSLT_FilePath
- TextOutput_FilePath
Sul caso okButton_Click() della mia forma, ho il seguente:
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();
}
All'interno del contesto del mio file XMLInput c'è un riferimento ai dati in un altro file XML - vedi sotto:
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>
L'attributo testo è dove è memorizzato il percorso del file XML esterno, nell'esempio di cui sopra, il nome del file XML sarebbe "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>
sto utilizzando Microsoft Visual Studion 2008 Professional Edition per testare la mia trasformare e lo scenario di cui sopra funziona esattamente come dovrebbe - il documento() facendo riferimento al file esterno in modo più specifico. Tuttavia, quando uso la mia app C# Winform e le chiamate ax saxon, il mio file di output contiene dati vuoti (righe vuote).
Dopo alcuni test e ricerche su Internet, sono giunto alla conclusione che il percorso relativo [nel mio XSLT] non viene applicato come dovrebbe. Sembra che le chiamate a saxon api elaborino la funzione document() dalla posizione del file transform.exe e non il file di input (che è quello che preferirei).
Ho cercato di fare più ricerche su Internet su questo problema e sono confuso dal fatto che il problema sia nel mio file XSLT o nelle chiamate a saxon all'interno dell'evento okButton_Click(). Inoltre, sono stato a visitare il sito Web di saxon e documentation per aiuto, ma senza alcun risultato.
ho aggiornato il XSLT secondo la vostra risposta e sto ancora ricevendo lo stesso risultato - dati vuoti – Lorentz
Vedo altri problemi con i tuoi campioni pubblicati, hai pubblicato un elemento 'Rows' con un elemento figlio' Path' con un attributo 'Text' ma il tuo codice esegue un' for-each select = "//Righe "' e quindi accede a '@ Text' di quegli elementi' Rows', non del figlio 'Path'. Quindi, in base agli esempi pubblicati, si potrebbe desiderare' for-each select = "// Rows/Path" ' –
Grazie Martin - hai ragione, ha aggiornato il post originale – Lorentz