我正在使用XSLT 1.0并有以下示例代码:
在我的XSLT中,我有一个包含XML路径的参数
<xsl:param name="sitespath"/>
我知道我可以将其作为文档加载,然后相应地进一步获取值,如下所示
<xsl:variable name="siteInfoPath" select="document($sitespath)/sitedata/region/site/language"/>
以上 siteInfoPath XSLT变量正在使用 / sitedata / region / site / language 数据加载文档,但是现在我想采用 PublishDate ,下面是XML样本格式
<?xml version="1.0"?>
<sitedata>
<resources>
<WorldwideSites>Worldwide sites</WorldwideSites>
<PublishedDate>10/3/2011 9:12:35 AM</PublishedDate>
</resources>
<region code="global" title="Global">
<site defaultLanguage="en" id="tcm:0-233-1" url="/english" countryCode="" title="" order="1">
<language code="en" pubId="tcm:0-233-1" pubPath="\english" Culture="en-GB" ShortDate="dd MMM yy" ShortDateShortDay="ddd dd MMM yy" ShortDateTime="dd MMM yy, HH:mm" LongDate="d MMMM, yyyy" LongDateTime="d MMMM, yyyy, HH:mm" LongDateExtendedShortDay="ddd dd MMM, yyyy" LongDateExtended="dddd, d MMMM, yyyy" LongDateExtendedTime="dddd, d MMMM, yyyy, HH:mm" MonthYear="MMMM, yyyy" OmniturePrefix="ek global:en:" OmnitureReportSuite="emirnewglobalenglish,emirnewibems" OmnitureDevReportSuite="emirglobalendev" sifr="Y" localTitle="" url="/english" mobileRedirect="true" flightStatusAlert="true" GoLiveDate="20071110" targetHost="http://fly1.com" hpSearchF="Yes" hpHotelsCars="Yes" hpMYB="Yes" hpOLCI="Yes" hpFStatus="Yes" hpServicesF="Yes">English</language>
</site>
我是否需要使用其他变量并需要像这样加载文档
<xsl:variable name="siteInfoDate" select="document($sitespath)/sitedata/resources/PublishedDate"/>
我不想再次加载相同的xml ...请建议!!
答案 0 :(得分:2)
动态Xpath评估通常需要在XSLT 1.0和XSLT 2.0中使用扩展函数。这不是一个好主意,因为您可能会或可能不会找到这样的扩展,并可能最终需要编写自己的扩展。此外,代码的可移植性也被破坏了。
我是否需要使用其他变量并需要像这样加载文档
<xsl:variable name="siteInfoDate" select="document($sitespath)/sitedata/resources/PublishedDate"/>
我不想再次加载相同的xml ...请建议!!
这实际上是解决问题的最佳方法。
一种普遍的误解是,对具有相同URL的document()
函数发出多个调用会加载并多次解析同一文档。
W3C XSLT specification defines that the URL typically is loaded and parsed only once -- the function is stable,无论调用document()
函数多少次。
因此,没有任何效率损失。
要消除您的恐惧,请(这会帮助您安然入睡,但根本不需要):
<xsl:variable name="vDoc" select="document($sitespath)"/>
<xsl:variable name="siteInfoDate"
select="$vDoc/sitedata/resources/PublishedDate"/>
<xsl:variable name="siteInfoPath"
select="$vDoc/sitedata/region/site/language"/>
在这里,您只需使用document()
函数进行一次调用即可获得该文档。
答案 1 :(得分:0)
通常在XSL 1中,您必须使用扩展功能,因为没有直接的方法来实现这一点。这在某种程度上取决于您使用的实际解析器,但这是一个与Xalan一起使用的示例,它支持可选的EXSLT functions:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:dyn="http://exslt.org/dynamic">
<xsl:param name="sitespath">/sitedata/region/site/language</xsl:param>
<xsl:template match="/">
<xsl:message>
<xsl:value-of select="dyn:evaluate($sitespath)/@code"/>
</xsl:message>
</xsl:template>
</xsl:stylesheet>
evaluate()
函数将动态评估XPath字符串,上面的示例将在code
的值所评估的任何XPath下将其打印出属性sitespath
的值。
如果您不使用Xalan,那么您需要做的可能会有所不同。例如,对于Saxon解析器,您需要做的就是将名称空间dyn
URI更改为http://saxon.sf.net/
以获取更新版本,或更改为http://icl.com/saxon
更旧版本。