首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >XProc:具有中间文件的多个XSLT转换

XProc:具有中间文件的多个XSLT转换
EN

Stack Overflow用户
提问于 2012-05-17 13:24:15
回答 1查看 2.3K关注 0票数 2

我需要使用中间XML文件进行几次XSLT转换。(我需要这些文件,因为后面的步骤加载中间文件时,实际情况要复杂一些)

代码语言:javascript
运行
复制
first.xml ------------>   intermediate.xml ------------> final.xml
          first.xsl                         final.xsl

我想制造一种XProc哌替比林。我试图编写以下代码,但这给了我一个错误:

代码语言:javascript
运行
复制
SCHWERWIEGEND: runxslt.xpl:26:44:err:XD0011:Could not read: intermediate.xml 
17.05.2012 15:15:35 com.xmlcalabash.drivers.Main error
SCHWERWIEGEND: It is a dynamic error if the resource referenced by a p:document element does not exist, cannot be accessed, or is not a well-formed XML document.
17.05.2012 15:15:35 com.xmlcalabash.drivers.Main error
SCHWERWIEGEND: Underlying exception: net.sf.saxon.s9api.SaxonApiException: I/O error reported by XML parser processing file:/<somepath>/intermediate.xml:
/<somepath>/intermediate.xml (No such file or directory)

( SCHWERWIEGEND的意思是致命的)所以很明显,文件intermediate.xml还没有被写入。

这是我使用过的xpl-document:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
  xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0">

  <p:input port="source">
    <p:document href="first.xml"/>
  </p:input>

  <p:output port="result" sequence="true">
    <p:empty/>
  </p:output>

  <p:xslt name="first-to-intermediate">
    <p:input port="stylesheet">
      <p:document href="first.xsl"/>
    </p:input>
    <p:input port="parameters">
      <p:empty/>
    </p:input>
  </p:xslt>

  <p:store href="intermediate.xml" />

  <p:xslt>
    <p:input port="source">
      <p:document href="intermediate.xml"/>
    </p:input>
    <p:input port="stylesheet">
      <p:document href="final.xsl"/>
    </p:input>
    <p:input port="parameters">
      <p:empty/>
    </p:input>
  </p:xslt>

  <p:store href="final.xml"/>

</p:declare-step>

为了完整起见:这些是转换文件:

source.xml:

代码语言:javascript
运行
复制
<root>
  <element name="A" />
</root>

first.xsl:

代码语言:javascript
运行
复制
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  <xsl:output indent="yes"/>

  <xsl:template match="root">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>
  <xsl:template match="element">
    <intermediate name="A" />
  </xsl:template>

</xsl:stylesheet>

final.xsl:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  <xsl:output indent="yes"/>

  <xsl:template match="root">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>
  <xsl:template match="intermediate">
    <final name="A" />
  </xsl:template>

</xsl:stylesheet>

这里有一个关于实际应用程序的说明(当然,上面是一个简化)。

  1. 第一步:将源代码转换为更适合我处理的东西。输出:companies.xml
  2. Take步骤1的输出,并由此创建索引文件(index.xml)。索引文件必须是可编辑的manually.
  3. The第三步是合并由步骤1和2创建的文件并创建最终的xml (final.xml)

索引文件必须写入磁盘,并且我必须能够自行运行最后一步(这是一个不同的问题-我会编写一个不同的管道)

companies.xml的输出(步骤1)是可选的,它可以保存在内存中(但可能会变大)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-17 18:13:14

我不太清楚为什么XMLCalabash不在这里工作。我认为逻辑在原则上是可行的,但显然XMLCalabash将文件写入磁盘的时间推迟到稍后,甚至可能会拖到最后。不知道为什么。

但是有一个优雅的解决方案,因为在继续处理之前不需要存储中间结果。事实上,最好不要使用硬编码的负载和存储。相反,可以使用如下内容:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?> 
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" 
  xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0"> 

  <p:input port="source" sequence="true"/> 
  <p:input port="parameters" kind="parameter"/>
  <p:output port="result" sequence="true"/> 

  <p:xslt name="first-to-intermediate"> 
    <p:input port="stylesheet"> 
      <p:document href="first.xsl"/> 
    </p:input> 
  </p:xslt> 

  <p:xslt> 
    <p:input port="stylesheet"> 
      <p:document href="final.xsl"/> 
    </p:input> 
  </p:xslt> 

</p:declare-step> 

它需要对XMLCalabash进行稍微不同的调用。就这样说吧:

代码语言:javascript
运行
复制
java -jar Calabash.jar -i source=first.xml -o result=final.xml runxslt.xpl

使用-i,您可以将输入源绑定到输入文件,但是从脚本外部开始,因此不需要进行硬编码。与-o类似,您可以将输出重定向到目标文件。

我还向代码中添加了一个“参数”输入,这些输入会自动连接到p:xslt。这样,您就不需要指定带有p:空的那些。它还允许将参数值从命令行传递到那些xslt中。

因为我删除了p:store,所以第二个p:xslt的“源”输入也是不必要的。默认情况下,第一个p:xslt的结果直接进入以下步骤的(主要)源输入。

-编辑--

为了详细说明我自己的注释,您可以执行p:存储并重用第一个p:xslt的输出,而无需从磁盘加载中间文档。你可以这样做:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?> 
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" 
  xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0"> 

  <p:input port="source" sequence="false"/> 
  <p:input port="parameters" kind="parameter"/>
  <p:output port="result" sequence="false"/> 

  <p:xslt name="first-to-intermediate"> 
    <p:input port="stylesheet"> 
      <p:document href="first.xsl"/> 
    </p:input> 
  </p:xslt> 

  <p:store href="intermediate.xml"/>

  <p:xslt> 
    <p:input port="source"> 
      <p:pipe step="first-to-intermediate" port="result"/> 
    </p:input> 
    <p:input port="stylesheet"> 
      <p:document href="final.xsl"/> 
    </p:input> 
  </p:xslt> 

</p:declare-step> 

注意,我在声明步骤的输入和输出中都将sequence=true更改为false。存储中间结果的序列需要特别小心。这样可以防止错误的发生。

哈哈!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10636613

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档