SAXONHE 9.2.1.1 API ファイルを使用して XML データをプレーン テキストに変換するアプリケーションがあります。私のフォームにはテキストボックスがあります
- XMLInput_FilePath
- XSLT_FilePath
- TextOutput_FilePath
私のフォームのokButton_Click()イベントには、次のものがあります。
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();
}
XMLInput ファイルのコンテキスト内に、別の XML ファイル内のデータへの参照があります。以下を参照してください。
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>
Text 属性は、外部 XML ファイル パスが格納される場所です。上記の例では、XML ファイル名は「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>
私は Microsoft Visual Studion 2008 Professional Edition を使用して変換をテストしていますが、上記のシナリオは、外部ファイルをより具体的に参照する document() が正確に機能します。ただし、C# Winform アプリと saxon API 呼び出しを使用すると、出力ファイルに空白のデータ (空白行) が含まれます。
いくつかのテストとインターネット検索の後、[XSLT 内の] 相対パスが適切に適用されていないという結論に達しました。saxon api 呼び出しは、入力ファイルではなく、transform.exe ファイルの場所から document() 関数を処理しているようです (これは私が好むものです)。
この問題についてさらにインターネット検索を試みましたが、問題が XSLT ファイルにあるのか、okButton_Click() イベント内の saxon API 呼び出しにあるのか混乱しています。さらに、私は saxon の Web サイトとドキュメントに助けを求めましたが、役に立ちませんでした。