调用包含的模板时“If-element”没有反应
Posted
技术标签:
【中文标题】调用包含的模板时“If-element”没有反应【英文标题】:"If-element" does not react when calling included template 【发布时间】:2021-08-10 03:35:55 【问题描述】:我希望构建一个简单的逻辑来让用户定义应该调用哪些模板。该代码说明了一个最小化的示例。当有许多模板时,该设置非常有用,例如我正在构建的输出是大约 2.600 行 Xhtml 代码。那么能够排除几个模板而只关注其中一些模板是非常好的。
我已经成功创建了上述设置(以前),将 XML 作为源文件和模块化代码。我怀疑这是我将 JSON 作为源文件的设置以及导致问题的代码改编。
下面的代码应该允许用户将变量“build-with-books”从 0 切换到 1,如果设置为 1,“if”元素应该调用包含的模板。
我确信有许多“更智能”的方法可以解决我的需求。目前我只是想了解为什么我的代码不遵循打开/关闭元素构建的所需逻辑。
XSLT fiddle 已失效,所以我将代码粘贴到下面:
数据:
<data>
"books":
"Wonderland": 43
,
"beverage":
"Falcon": 12
</data>
principal.xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ix="http://www.example.com/1"
xmlns:xbrli="http://www.example.com/2"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<!-- Block all data that has no user defined template -->
<xsl:mode on-no-match="shallow-skip"/>
<!-- Includes -->
<xsl:include href="books.xsl"/>
<!-- Module selector -->
<xsl:variable name="build-with-books">0</xsl:variable>
<!-- Attribute-sets -->
<xsl:attribute-set name="books">
<xsl:attribute name="category">Adventure</xsl:attribute>
</xsl:attribute-set>
<!-- Main template -->
<xsl:template match="data">
<!-- Parse JSON to XML, results in XML map -->
<xbrli:xbrl>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</xbrli:xbrl>
<!-- Call template -->
<xsl:if test=" $build-with-books = '1' ">
<xsl:call-template name="books"/>
</xsl:if>
</xsl:template>
</xsl:transform>
支持模块:books.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ix="http://www.example.com/1"
xmlns:xbrli="http://www.example.com/2"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<!-- Create elements -->
<xsl:template name="books" match="*[@key = 'books']//*[@key and not(*)]">
<xsl:element name="ix:@key" use-attribute-sets="books">.</xsl:element>
</xsl:template>
</xsl:transform>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:xbrl xmlns:ix="http://www.example.com/1" xmlns:xbrli="http://www.example.com/2">
<ix:Wonderland category="Adventure">43</ix:Wonderland>
</xbrli:xbrl>
变量“build-with-books”设置为 0 时的预期结果
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:xbrl xmlns:ix="http://www.example.com/1" xmlns:xbrli="http://www.example.com/2">
</xbrli:xbrl>
变量“build-with-books”设置为 1 时的预期结果
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:xbrl xmlns:ix="http://www.example.com/1" xmlns:xbrli="http://www.example.com/2">
<ix:Wonderland category="Adventure">43</ix:Wonderland>
</xbrli:xbrl>
【问题讨论】:
如果从books
模板中删除match
会发生什么?我猜是因为您将模板应用于来自json-to-xml()
的所有结果元素,所以该模板仍然匹配。
@DanielHaley,如果我从书籍模板中删除匹配项,并将变量“build-with-books”保持为零,则输出不会使用元素“Wonderland”构建。这是正确的行为,但如果我也将“build-with-book”更改为 1,则完整的输出为空。
【参考方案1】:
开始
从 principal.xsl 中删除这部分:(调用模板使用当前上下文,这仍然是您在数据上的匹配项)
<!-- Call template -->
<xsl:if test=" $build-with-books = '1' ">
<xsl:call-template name="books"/>
</xsl:if>
并从中删除@name 属性
<xsl:template name="books" match="*[@key = 'books']//*[@key and not(*)]">
选项:1
将books.xls 中的匹配模板更改为如下所示(它将直接使用您的全局$build-with-books
)
<xsl:template match="*[$build-with-books='1'][@key = 'books']//*[@key and not(*)]">
<xsl:element name="ix:@key" use-attribute-sets="books">.</xsl:element>
</xsl:template>
选项:2
在您的 principal.xsl 中使用xsl:next-match:(它将首先使用具有更高优先级的模板来检查全局$build-with-books
)
添加这个:
<xsl:template match="*[@key = 'books']" priority="10">
<xsl:if test="$build-with-books='1'">
<xsl:next-match/>
</xsl:if>
</xsl:template>
【讨论】:
以上是关于调用包含的模板时“If-element”没有反应的主要内容,如果未能解决你的问题,请参考以下文章
调用 StreamController.sink.add 时 StreamBuilder 没有反应
c# datagrid模板列checkbox,运行点击没有反应,checked为假.