【问题标题】:How to get XML node value in XSLT if we have got XML path in PARAM如果我们在 PARAM 中有 XML 路径,如何在 XSLT 中获取 XML 节点值
【发布时间】:2011-10-03 05:43:42
【问题描述】:

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

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    动态 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() 函数即可获取文档。

    【讨论】:

      【解决方案2】:

      一般而言,在 XSL 1 中,您必须为此使用扩展函数,因为没有直接的方法来完成此操作。这在一定程度上取决于您使用的实际解析器,但这里有一个与支持可选 EXSLT functions 的 Xalan 一起使用的示例:

      <?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 的值,在 sitespath 的值计算为的 XPath 下。

      如果您不使用 Xalan,那么您需要做的可能会有所不同。例如,对于 Saxon 解析器,您只需将命名空间 dyn URI 更改为 http://saxon.sf.net/ 以获取更新的版本,或更改为 http://icl.com/saxon 以获取旧版本。

      【讨论】:

        猜你喜欢
        • 2020-12-15
        • 1970-01-01
        • 1970-01-01
        • 2012-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-29
        相关资源
        最近更新 更多