如果我们在PARAM中有XML路径,如何在XSLT中获取XML节点值

时间:2011-10-03 05:43:42

标签: xml xslt

我正在使用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 ...请建议!!

2 个答案:

答案 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更旧版本。