Как получить значение узла XML в XSLT, если у нас есть путь XML в PARAM - PullRequest
1 голос
/ 03 октября 2011

Я использую XSLT 1.0 и ниже приведен пример кода:

В моем XSLT у меня есть параметр с моим XML-путем

<xsl:param name="sitespath"/>

Я знаю, что могу загрузить его как документ, а затем получить соответствующие значения, как показано ниже

  <xsl:variable name="siteInfoPath" select="document($sitespath)/sitedata/region/site/language"/>

выше siteInfoPath XSLT varaible загружает документ с данными / 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 ]

2 голосов
/ 03 октября 2011

Динамическая оценка Xpath в целом требует использования функции расширения - как в XSLT 1.0, так и в XSLT 2.0. Это не очень хорошая идея, потому что вы можете или не можете найти такое расширение, и вам может понадобиться написать свое собственное. Кроме того, переносимость кода разрушена.

Нужно ли использовать другую переменную и нужно загрузить документ, подобный этому

<xsl:variable name="siteInfoDate" select="document($sitespath)/sitedata/resources/PublishedDate"/>

Я не хочу загружать тот же xml снова ... пожалуйста, предложите !!

На самом деле это лучший способ решить проблему.

Широко распространено заблуждение, что при вызове нескольких вызовов функции document() с одним и тем же URL-адресом загружается и анализируется один и тот же документ более одного раза.

Спецификация W3C XSLT определяет, что URL обычно загружается и анализируется только один раз - функция стабильна , независимо от того, сколько раз вызывается функция 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().

0 голосов
/ 03 октября 2011

Как правило, в XSL 1 вам придется использовать для этого функцию расширения, поскольку прямого способа сделать это не существует.Это в некоторой степени зависит от фактического парсера, который вы используете, но вот пример, который работает с Xalan, который поддерживает необязательные функции EXSLT :

<?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 для более старых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...