应用程序使用saxonHE(9.2.1.1)api处理针对多个XML文件的XSLT(v2.0)

Lor*_*ntz 6 c# xslt saxon .net-3.5 winforms

我有一个应用程序使用SAXONHE 9.2.1.1 api文件将XML数据转换为纯文本.我的表单有文本框

  1. XMLInput_FilePath
  2. XSLT_FilePath
  3. 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();
}
Run Code Online (Sandbox Code Playgroud)

在我的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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

我正在使用Microsoft Visual Studion 2008专业版来测试我的转换,上面的场景完全正常 - 文档()更具体地引用外部文件.但是,当我使用我的C#Winform应用程序和saxon api调用时,我的输出文件包含空白数据(空行).

经过几次测试和互联网搜索后,我得出的结论是[我的XSLT]中的相对路径没有应用.似乎saxon api调用从transform.exe文件的位置处理document()函数而不是输入文件(这是我更喜欢的).

我一直在尝试在这个问题上做更多的互联网搜索,我对这个问题是在我的XSLT文件中还是在okButton_Click()事件中的saxon api调用中感到困惑.此外,我去过撒克逊的网站和文档寻求帮助,但无济于事.

Mar*_*nen 1

在您的 XSLT 中,使用

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

如果您希望相对于输入文档(而不是样式表)解析相对 URL。