在coldfusion 8中使用相对路径调用xslt document()函数

时间:2011-10-17 08:18:46

标签: coldfusion xslt coldfusion-8

在XSL样式表中,我正在尝试使用document()函数和xml文件的相对路径(如果我正确理解XSLT规范,这应该是可能的),但由于某种原因,它看起来不像加载文件。使用绝对URI的相同代码按预期工作。我正在尝试加载的XML文件与样式表位于同一文件夹中。

问题是,我是否遗漏了Coldfusion 8 XSLT解析器中的document()函数如何解析相对路径的问题?我正在使用XmlTransform来调用我的CF组件中的XSLT解析器。

文件夹结构(简体,docroot =域名,例如http://www.example.com/):

docroot/html/xsl/stylesheet.xsl 
docroot/html/xsl/translations.xml
docroot/backend.cfc

调用文档函数的XSLT:

<h1>We should have hello after this text</h1>

<xsl:for-each select="document('translations.xml')">
    <h2>hello</h2>
</xsl:for-each>

<h1>We should have hello before this text</h1>

在上面的代码中,如果我将document('translation.xml')替换为document('http://www.example.com/html/xsl/translation.xml'),代码将按预期工作。但是,我希望避免将域硬编码到语句中,因为它会使样式表变得不那么便携。

我正在尝试加载的XML:

<?xml version="1.0" encoding="utf-8"?>
<translations>
    <fi>
        <insured>Vakuutettu</insured>
    </fi>
    <se>
        <insured>Försäkrad</insured>
    </se>
</translations>

ColdFusion组件backend.cfc中的代码,它启动XSL解析器:

...
<cfoutput>#XmlTransform(obj, xsltProductTable04, xslParameters)#</cfoutput>
...

xsltProductTable04是一个指向我正在加载的样式表的变量,它的值为html/xsl/stylesheet.xsl。我是否可以使用相对于cfc组件的URI加载样式表?

更新

根据Dimitre Novatchev的建议,我尝试逐步删除URL的每个部分(例如/html/xsl/translation.xml,/xsl/translation.xml等),但这些组合都不起作用。甚至可以在URL的开头使用和不使用正斜杠来尝试。

更新2

我目前解决此问题的方法是在样式表之外构建一个绝对URL,然后将其作为参数传递给样式表。这是有效的,在我当前的项目中实际上是一个更好的解决方案,因为它允许我简化XSL,因为我不需要关心在XSL中选择正确的语言了。但它仍然只是原始问题的解决方法。如果有人有更多关于为什么CF表现的信息,那么我很乐意听到它。

1 个答案:

答案 0 :(得分:3)

我没有对XSLT或xmlTransform()做过多少工作,但我读了docs,其中说:

  

如果XSLT代码包含具有相对路径的include语句,则ColdFusion将相对于XSLT文件的位置或XSL字符串(当前ColdFusion页面的位置)解析它们。

我测试了这两个,它们工作正常。您的问题似乎是您将XSL作为字符串传递给xmlTransform(),因此当XSLT处理器看到对“translations.xml”的引用时,它必须查看它相对于调用代码,而不是相对于原始XML文件(据其所知,它可能在任何地方:毕竟它收到的所有内容都是字符串)。

所以我可以通过制作两个mod之一来使你的代码工作:

第一个可以传入PATH文件,例如:

XmlTransform(obj, expandPath("xsl/stylesheet.xsl"), xslParameters)

这样xmlTransform()调用就知道了XSL文件的位置,所以知道如何计算相对于XSL文件本身的路径。

或者其次,将XSL文件中的translations.xml相对于代码而不是XSL文件,例如:

<xsl:for-each select="document('xsl/translations.xml')">

这两种方法都适用于我。我认为第一个更便于携带。

有意义吗?