将局部变量更改为全局变量不起作用
Posted
技术标签:
【中文标题】将局部变量更改为全局变量不起作用【英文标题】:Change local to global variable does not work 【发布时间】:2021-11-14 04:24:12 【问题描述】:我计划集中所有变量,因此将它们设置为位于模板之外的全局变量。如下所述,如果在模板中本地添加它,完全相同的变量将起作用。代码被大量最小化以适应 SO 问题。全局变量的数量会更多。
问题:
将变量移出模板并将其用作全局变量不会返回预期结果。
您在此xsltfiddle 中找到相同的代码。
代码:
数据 (JSON):
<data>
"report":
"facts": [
"xbrl:concept": "se:CompanyName",
"value": "Great Company Ltd"
]
</data>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:output method="xhtml" indent="yes" html-version="5"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<xsl:apply-templates select="json-to-xml(.)/*"/>
</xsl:template>
<!-- Global variable -->
<xsl:variable name="headings" select="//*[@key='xbrl:concept'][. = 'se:CompanyName']/../*[@key='value']"/>
<xsl:template match="//*[@key='facts']">
<!-- Local variable works when uncommented -->
<!--<xsl:variable name="headings" select="//*[@key='xbrl:concept'][. = 'se:CompanyName']/../*[@key='value']"/>-->
<xsl:value-of select="$headings"/>
</xsl:template>
</xsl:stylesheet>
结果:
<?xml version="1.0" encoding="UTF-8"?>
预期结果:
<?xml version="1.0" encoding="UTF-8"?>Great Company Ltd
【问题讨论】:
Martin Honnen 解释了为什么您的更改不起作用,但我也会退后一步,询问您想要实现的目标。与大多数编程语言一样,最好尽可能避免使用 XSLT 中的全局变量:它们会降低代码的可重用性。 通过在 XSLT 中使用解析的 JSON 数据,选择字符串变得相当长,这会影响代码的概览和可见性,尤其是在可能将代码移交给其他开发人员时。我希望实现的计划是让选择字符串成为全局变量的一部分,从而将长选择字符串分组在一个 XSLT 文件中。此外,通过将所有变量分组,我想看看是否可以缩小字符串长度。 那么也许你需要更多地使用函数而不是变量。 【参考方案1】:您的策略“我计划集中所有变量,因此将它们设置为驻留在模板之外的全局变量。”没有任何意义,全局变量是相对于全局上下文项计算的,任何局部变量都是相对于模板的上下文项或模板中的进一步嵌套指令进行计算的。
因此,您的全局尝试 <xsl:variable name="headings" select="//*[@key='xbrl:concept'][. = 'se:CompanyName']/../*[@key='value']"/>
将在全局上下文项中查找属性为 key
的元素,据我所知,该元素是您的文档,其中包含一些 JSON 的 data
元素。显然,该文档没有任何此类元素。
令人怀疑的是,您的所有路径都是绝对路径,从根目录开始以//
开头并查看文档中的任何位置,但目前您甚至没有正确的根目录来使用“全局变量”。
你可以试试例如
<xsl:variable name="json-xml-doc" select="json-to-xml(data)"/>
然后使用例如
<xsl:variable name="headings" select="$json-xml-doc//*[@key='xbrl:concept'][. = 'se:CompanyName']/../*[@key='value']"/>
但我不建议,最后,我认为,大多数查找表达式更容易编写、阅读和维护,更短的阅读、理解和维护,如果它们与你的上下文项相关,可能通常更有效.
【讨论】:
以上是关于将局部变量更改为全局变量不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如果全局不起作用,在Python中访问for循环之外的变量?