"If-element" 调用包含的模板时没有反应
"If-element" does not react when calling included template
我希望构建一个简单的逻辑,让用户定义应该调用哪些模板。该代码说明了一个最小化的示例。当有很多模板时,该设置非常有用,例如我构建的输出是大约 2.600 行 XHTML 代码。那么能够排除几个模板只关注其中的一些模板是非常好的。
我已经(以前)成功创建了上述设置,将 XML 作为源文件和模块化代码。我怀疑是我的设置将 JSON 作为源文件和导致问题的代码改编。
下面的代码应该允许用户将变量“build-with-books”从 0 切换到 1,如果设置为 1,“if”元素应该调用包含的模板。
我相信有很多“更聪明”的方法可以解决我的需求。目前我只是想了解为什么我的代码不遵循切换 on/off 元素构建的所需逻辑。
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>
开始
从 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>
我希望构建一个简单的逻辑,让用户定义应该调用哪些模板。该代码说明了一个最小化的示例。当有很多模板时,该设置非常有用,例如我构建的输出是大约 2.600 行 XHTML 代码。那么能够排除几个模板只关注其中的一些模板是非常好的。
我已经(以前)成功创建了上述设置,将 XML 作为源文件和模块化代码。我怀疑是我的设置将 JSON 作为源文件和导致问题的代码改编。
下面的代码应该允许用户将变量“build-with-books”从 0 切换到 1,如果设置为 1,“if”元素应该调用包含的模板。
我相信有很多“更聪明”的方法可以解决我的需求。目前我只是想了解为什么我的代码不遵循切换 on/off 元素构建的所需逻辑。
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>
开始
从 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>