在Cocoon中匹配选择器取决于另一个xml文件

时间:2014-02-14 20:52:29

标签: xml xslt apache-cocoon

我正在尝试在Cocoon中编写一个管道,该管道匹配“* .myxml”模式,然后读取(使用generate type =“file”)XML文件。这个XML文件是这样形成的(包含许多文件):

<result>
   <file>
       <name>a.myxml</name>
       <source>b.xml</source>
       <transform>c.xslt</transform>
   </file>
   ...
</result>

因此,如果模式是a.myxml,我想读取b.xml并使用此XML文件动态应用c.xslt。我希望能够添加新文件(使用自己的.xml和.xslt),而无需每次都修改管道。

有可能吗?这有选择器吗?有没有办法将XML文件的内容(如XPath选择器文件[/ name = {1} .myxml] / source或其他内容)作为generate和转换的src传递?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

它在Cocoon中比平时略微复杂,但我创建了一个我认为你想要的样本。

在站点地图中:

<map:pipeline>
  <map:match pattern="*.myxml">
    <map:generate src="my.xml"/>
    <map:transform src="sf-myxml.xslt">
      <map:parameter name="myxml" value="{1}.myxml"/>
    </map:transform>
    <map:transform type="include"/>
    <map:serialize type="xml"/>
  </map:match>

  <map:match pattern="myxml/**">
    <map:generate src="{1}"/>
    <map:transform src="{request-param:stylesheet}"/>
    <map:serialize type="xml"/>
  </map:match>
</map:pipeline>

因此,匹配* .myxml会从动态配置文件生成XML。

<result>
  <file>
    <name>a.myxml</name>
    <source>b.xml</source>
    <transform>c.xslt</transform>
  </file>

  <file>
    <name>x.myxml</name>
    <source>y.xml</source>
    <transform>c.xslt</transform>
  </file>

</result>

使用sf-myxml.xslt将其转换为Cinclude调用:

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
   xmlns:ci="http://apache.org/cocoon/include/1.0"
   exclude-result-prefixes="xs xd"
   version="2.0">


  <xsl:param name="myxml"/>

  <xsl:template match="/result">
    <xsl:copy>
        <xsl:apply-templates select="file[name eq $myxml]"/>
    </xsl:copy>
  </xsl:template>


  <xsl:template match="file">
    <ci:include src="cocoon:/myxml/{source}?stylesheet={transform}"/>
  </xsl:template>


</xsl:stylesheet>

找到正确的&lt; file&gt;元素并使用&lt; source&gt;和&lt; transform&gt;元素。例如,对于调用“/a.myxml”,这会生成:

 <ci:include src="cocoon:/myxml/b.xml?stylesheet=c.xslt"/>

这个茧:/调用&lt; cinclude&gt;然后匹配下一个&lt; map:match&gt;,其中,在上面的示例中,b.xml由c.xslt转换。我尝试了它,但它确实有效。

这是b.xml:

<page/>

这是y.xml:

<page title="z.myxml"/>

这是c.xslt:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
  exclude-result-prefixes="xs xd"
  version="2.0">

  <xsl:template match="page">
    <html><head><title><xsl:value-of select="@title"/></title></head><body><h1><xsl:value-of select="@title"/></h1></body></html>
  </xsl:template>

</xsl:stylesheet>

在调用z.myxml时调用a.myxl和标题“z.myxml”时没有标题。希望这是你想要的。

此致

Huib Verweij。