2012-04-12 20 views
6

XMLデータをプレーンテキストに変換するためにSAXONHE 9.2.1.1 APIファイルを使用するアプリケーションがあります。内saxonHE(9.2.1.1)apiを使用して複数のXMLファイルに対してXSLT(v2.0)を処理するアプリケーション

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(); 
} 

:私のフォームは

  1. XMLInput_FilePath
  2. XSLT_FilePath
  3. TextOutput_FilePath私のフォームのokButton_Click()イベントで

、私は次のようしているためにテキストボックスを持っています私の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> 

テキスト属性は、外部の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を使用していますし、それが必要として、上記のシナリオが正確に動作します - 文書を()より具体的には外部ファイルを参照します。しかし、C#Winformアプリケーションとsaxon API呼び出しを使用すると、出力ファイルに空白のデータ(空白行)が含まれています。

いくつかのテストとインターネット検索の結果、[XSLT内の]相対パスが適用されていないとの結論に至りました。 saxon API呼び出しは、document()関数をtransform.exeファイルの場所から処理し、ではなくの入力ファイル(これが私が好むものです)であると思われます。

私はこの問題についてより多くのインターネット検索をしようとしていますが、その問題が自分のXSLTファイルにあるのか、okButton_Click()イベント内のsaxon API呼び出しにあるのか混同しています。さらに、私はsaxonのウェブサイトとdocumentationに行ってきましたが、役に立たないです。あなたのXSLTで

答えて

1

、あなたは相対URLを入力文書(とないスタイルシート)に関連した解決されたことにしたい場合は

<xsl:apply-templates select ="document($_intfFileName, /)/*[@Name=$_intfModelName]/*"> 

を使用しています。

+0

私はあなたの返事によるXSLTを更新し、私はまだ同じを取得しています結果 - 空白のデータ – Lorentz

+0

投稿されたサンプルにいくつかの問題がありますが、 'Text'属性を持つ' Path'子要素を持つ 'Rows'要素を投稿しましたが、あなたのコードは' for-each select = /行 "を選択して、' Path'子ではなく 'Rows'要素の' @ Text'にアクセスしますので、ポストされたサンプルに基づいて 'for-each select =" // Rows/Path " 。 –

+0

ありがとうマーティン - あなたは正しいです。元の投稿を更新しました。 – Lorentz

0

ザクセンヘルプのメーリングリストに私の質問を投稿した後、サクソニカのマイケル・ケイは私にこの問題を助けました。エラーは私のサクソンAPI呼び出し(C#アプリケーション)にありました。以下は、更新されたコードです:。

private void okButton_Click(object sender, EventArgs e) { 
    Processor processor = new Processor(); 
    XdmNode input = processor.NewDocumentBuilder().Build(new Uri(inputFile)); 
    XsltCompiler compiler = processor.NewXsltCompiler(); 
    compiler.BaseUri = new Uri(inputFile); 
    XsltTransformer xsltTransformer = compiler.Compile(new Uri(transformFileTextBox.Text)).Load(); 
    xsltTransformer.InitialContextNode = input; 
    Serializer serializer = new Serializer(); 
    serializer.SetOutputFile(writeFile); 
    xsltTransformer.Run(serializer); 
    xsltTransform_FileStream.Close(); 
    modelFileStream.Close(); 
} 

「問題は、そのベースURIは不明である相対URI を解決するために)あなたは(文書を呼び出していることですが、あなたが 相対URIを計算するサブ・ビフォアを使用しているため、引数は文字列なので、 というベースURIはスタイルシートのURIです。 ストリームからスタイルシートを作成したため、スタイルシートのベースURIは不明です。この場合、Saxonは現在の作業ディレクトリに をデフォルト設定します。あなたは XsltCompiler.BaseUriプロパティを使用してベースURIを設定することができます「 - 。マイケル・ケイ

だから、ここで私は両方のFileStream変数

  • がXsltCompilerオブジェクトを作成し、BASEURIを設定削除

    • をやったことあります入力ファイルに
    • は、 '新しいUri(ファイル名)'署名でFileStream署名を置き換えました
    • このコード行が削除されました 'xsltTransformer.InputXmlResolver = null;'

    それがあるべきとして私の出力があり、これを解決するための彼の助けのためのSaxonicaのマイケル・ケイに感謝 - 。。ローレンツ

  • 関連する問題