Включение значения переменной в путь выбора XSL не работает - PullRequest
0 голосов
/ 20 февраля 2020

Я не могу полностью разобраться с этим.

Итак, у меня есть этот внешний XML файл данных:

<?xml version="1.0" encoding="UTF-8"?>
<Translations xmlns="http://www.publictalksoftware.co.uk/msa">
  <en>
    <Chairman>Chairman</Chairman>
    <Conductor>Conductor</Conductor>
    <Hospitality>Hospitality</Hospitality>
    <Prayer>Prayer</Prayer>
    <PublicTalk>Public Talk</PublicTalk>
    <Reader>Reader</Reader>
    <ServiceTalk>Service Talk</ServiceTalk>
    <Speaker>Speaker</Speaker>
    <Theme>Theme</Theme>
    <WTStudy>Watchtower Study</WTStudy>
  </en>
</Translations>

На него ссылаются в моем основном сценарии XSL, как это :

<xsl:variable name="Translations" select="document('Workbook-S-140-Compact_2020_v2_Translations.XML')"/>

Я могу извлечь значения из этого XML файла следующим образом:

<xsl:value-of select="$Translations/msa:Translations/msa:en/msa:ServiceTalk"/>

Приведенное выше извлечет перевод Engli sh. Дело в том, что в моем основном файле данных XML вверху есть следующее:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Workbook-S-140-Compact_2020_v2.xsl"?>
<MeetingWorkBook>
    <Settings>
        <LanguageCode>en</LanguageCode>
        <Direction>ltr</Direction>
        <EditorMode>1</EditorMode>
        <ForeignGroupMode>0</ForeignGroupMode>
        <Now Day="20" Month="2" Year="2020"/>
    </Settings>

Обратите внимание на запись LanguageCode? Я хотел использовать это так, чтобы мое преобразование было основано на коде языка. Поэтому я сначала добавил в свою XSL-файл вторую переменную:

  <xsl:variable name="LangCode">
    msa:<xsl:value-of select="//Settings//LanguageCode"/>
  </xsl:variable>

И изменил свой путь так:

<xsl:value-of select="$Translations/msa:Translations/{$LangCode}/msa:ServiceTalk"/>

Но это не нравится. Я не могу понять, как вставить код языка в запрос пути. У меня много таких строк перевода, поэтому я ищу простое решение, если это возможно.


Я также попытался сохранить переменную как:

  <xsl:variable name="LangCode">
    <xsl:value-of select="//Settings//LanguageCode"/>
  </xsl:variable>

И затем использовать:

<xsl:value-of select="$Translations/msa:Translations/msa:{$LangCode}/msa:ServiceTalk"/>

По-прежнему происходит сбой.

Можно ли настроить эту строку:

<xsl:variable name="Translations" select="document('Workbook-S-140-Compact_2020_v2_Translations.XML')"/>

Так, чтобы $Translations указывал на узел Translations/langcode? Имеет смысл?

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

Чтобы расширить правильный ответ @ Томалака, вы допустили несколько ошибок:

Во-первых:

  <xsl:variable name="LangCode">
    msa:<xsl:value-of select="//Settings//LanguageCode"/>
  </xsl:variable>

Здесь есть несколько неправильных вещей. Во-первых, пробел, предшествующий «msa:», является частью значения переменной и приведет к сбою сопоставления. Во-вторых, использование путей с несколькими операторами "//" довольно неоправданно дорого. В-третьих, вы создаете фрагмент дерева результатов, когда было бы гораздо проще создать строку:

<xsl:variable name="LangCode" select="concat('msa:', //Settings/LanguageCode)"/>

Далее вы неправильно понимаете, как переменные работают в XPath. Переменные представляют значения, а не части текста выражения (это не язык макросов, как сценарий оболочки, это язык выражений, подобный Javascript). Ваша переменная может использоваться везде, где вы можете использовать строковый литерал в кавычках, например [contains(., 'fred')] может стать contains(., $var). Его нельзя использовать вместо частей выражения, где строковый литерал не будет разрешен. И фигурные скобки для текстовой подстановки работают только в нескольких четко определенных контекстах, они никогда не используются для замены частей выражения (по крайней мере, до тех пор, пока вы не доберетесь до теневых переменных в XSLT 3.0, но это продвинутая топика c. ..)

1 голос
/ 20 февраля 2020

Вы не можете использовать шаблоны значений атрибутов для динамического построения выражения XPath.

Но вы можете использовать переменные в предикатах:

<xsl:value-of select="$Translations/msa:Translations/msa:*[local-name() = $LangCode]/msa:ServiceTalk"/>
...