在 XSL select 路径中包含变量值无效
Including a variable value in a XSL select path is not working
我不太明白这个问题。
所以我有这个外部 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"/>
以上将拉出英文翻译。事情是这样的,在我的主要 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
节点?有道理吗?
您不能使用属性值模板动态构造 XPath 表达式。
但是你可以在谓词中使用变量:
<xsl:value-of select="$Translations/msa:Translations/msa:*[local-name() = $LangCode]/msa:ServiceTalk"/>
为了扩展@Tomalak 的正确答案,您犯了几个错误:
首先:
<xsl:variable name="LangCode">
msa:<xsl:value-of select="//Settings//LanguageCode"/>
</xsl:variable>
这里有几处错误。首先,"msa:" 前面的空格是变量值的一部分,会导致匹配失败。其次,使用具有多个“//”运算符的路径非常昂贵。第三,当构建一个字符串要简单得多时,您正在构建一个结果树片段:
<xsl:variable name="LangCode" select="concat('msa:', //Settings/LanguageCode)"/>
接下来,您误解了变量在 XPath 中的工作方式。变量表示值,而不是表达式文本的一部分(它不是像 shell 脚本那样的宏语言,而是像 Javascript 这样的表达式语言)。您的变量可以用在任何您可能在引号中使用字符串文字的地方,例如 [contains(., 'fred')]
可以变成 contains(., $var)
。它不能用于代替不允许使用字符串文字的表达式部分。用于文本替换的花括号仅在少数明确定义的上下文中起作用,它们从不用于替换表达式的一部分(至少,直到您进入 XSLT 3.0 中的影子变量,但这是一个高级主题......)
我不太明白这个问题。
所以我有这个外部 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"/>
以上将拉出英文翻译。事情是这样的,在我的主要 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
节点?有道理吗?
您不能使用属性值模板动态构造 XPath 表达式。
但是你可以在谓词中使用变量:
<xsl:value-of select="$Translations/msa:Translations/msa:*[local-name() = $LangCode]/msa:ServiceTalk"/>
为了扩展@Tomalak 的正确答案,您犯了几个错误:
首先:
<xsl:variable name="LangCode">
msa:<xsl:value-of select="//Settings//LanguageCode"/>
</xsl:variable>
这里有几处错误。首先,"msa:" 前面的空格是变量值的一部分,会导致匹配失败。其次,使用具有多个“//”运算符的路径非常昂贵。第三,当构建一个字符串要简单得多时,您正在构建一个结果树片段:
<xsl:variable name="LangCode" select="concat('msa:', //Settings/LanguageCode)"/>
接下来,您误解了变量在 XPath 中的工作方式。变量表示值,而不是表达式文本的一部分(它不是像 shell 脚本那样的宏语言,而是像 Javascript 这样的表达式语言)。您的变量可以用在任何您可能在引号中使用字符串文字的地方,例如 [contains(., 'fred')]
可以变成 contains(., $var)
。它不能用于代替不允许使用字符串文字的表达式部分。用于文本替换的花括号仅在少数明确定义的上下文中起作用,它们从不用于替换表达式的一部分(至少,直到您进入 XSLT 3.0 中的影子变量,但这是一个高级主题......)