Ich habe eine Anwendung, die die SAXONHE 9.2.1.1 API-Dateien verwendet, um XML-Daten in reinen Text umzuwandeln. Meine Form hat Textfelder fürApp mit saxonHE (9.2.1.1) api zum Verarbeiten von XSLT (v2.0) gegen mehrere XML-Dateien
- XMLInput_FilePath
- XSLT_FilePath
- TextOutput_FilePath
Auf der okButton_Click() Ereignis meiner Form, ich habe folgendes:
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();
}
Innerhalb der Kontext meiner XMLInput-Datei gibt es einen Verweis auf Daten in einer anderen XML-Datei - siehe unten:
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>
Der Text Attribut ist, wo der externe XML-Dateipfad gespeichert ist, in dem obigen Beispiel der XML-Dateiname wäre "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>
Ich verwende Microsoft Visual Studion 2008 Professional Edition meine Transformation zu testen und das obige Szenario funktioniert genau so, wie es sein sollte - das Dokument() referenzieren die externe Datei genauer. Wenn ich jedoch meine C# -Winform-App und die saxon-API-Aufrufe verwende, enthält meine Ausgabedatei leere Daten (Leerzeilen).
Nach ein paar Tests und Internetrecherchen bin ich zu dem Schluss gekommen, dass der relative Pfad [in meinem XSLT] nicht richtig angewendet wird. Es scheint, dass die saxon api Aufrufe die Datei document() aus dem Speicherort der Datei transform.exe und nicht die Eingabedatei verarbeiten (was ich bevorzuge).
Ich habe versucht, mehr Internet-Suchen zu diesem Thema zu tun, und ich bin verwirrt, ob das Problem in meiner XSLT-Datei oder in den saxon API-Aufrufen innerhalb der okButton_Click() -Ereignis ist. Außerdem war ich auf der saxon Website und documentation um Hilfe, aber ohne Erfolg.
ich die XSLT aktualisiert entsprechend Ihrer Antwort und ich bin immer noch der gleiche Ergebnis -. blank Daten – Lorentz
ich einige andere Probleme mit Ihrer geschrieben Proben sehen, Sie haben ein 'Rows' Element mit einem' Path' Kind-Element mit einem 'Text' geschrieben Attribut noch Ihren Code ein nicht' for-each select = "//Rows "' und greift dann auf den '@ Text' dieser' Rows' Elemente zu, nicht auf das 'Path'-Kind. Also, basierend auf den geposteten Samples, könnte 'for-select =" // Rows/Path "' sein –
Danke Martin - du hast Recht Aktualisierter Originalbeitrag – Lorentz