为每个查询元素添加属性集
Add attribute-set per queried element
我正在使用一个平面 JSON 源文件,从分层树的角度来看。作为 XSLT 转换的一部分,我希望定义指示哪个元素应具有特定属性集的组。输出的元素顺序并不重要。
这是我的代码的最小化版本,所以我想将所有 settings/configuration/defitions 集中在 XSL 的顶部是有原因的。如果代码非常小,我认为直接在每个模板中添加请求的元素是有意义的。
我知道“if”元素行已被注释掉,可能需要使用正确的语法(和扩展)它们才能使解决方案起作用。
如果有另一种更好、更简单的定义组的方法也很好。
JSON:
<data>
{
"flat": {
"Milk": 12,
"Duck": 32,
"Beer": 8,
"Cow": 43
}
}
</data>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:item="http://www.example.com/1"
xmlns:inventory="http://www.example.com/2"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Categorization -->
<xsl:variable name="group-animals">Cow, Duck</xsl:variable>
<xsl:variable name="group-beverage">Milk, Beer</xsl:variable>
<!-- Variations of attribute settings -->
<xsl:attribute-set name="set-attributes-for-category-animals">
<xsl:attribute name="contextRef">animals</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="set-attributes-for-category-beverage">
<xsl:attribute name="contextRef">beverage</xsl:attribute>
</xsl:attribute-set>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<inventory>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</inventory>
</xsl:template>
<!-- Template -->
<!-- Planned logic: -->
<!--
If element defined in "group-animals" exist in JSON / XML map",
then use "set-attributes-for-category-animals"
If element defined in "group-beverage" exist in JSON / XML map",
then use "set-attributes-for-category-beverage"
-->
<xsl:template match="*[@key ='flat']">
<xsl:for-each select="*">
<!-- <xsl:if test=""> -->
<xsl:element
name="item:{@key}"
use-attribute-sets="set-attributes-for-category-animals"
>
<xsl:value-of select="text()"/>
</xsl:element>
<!-- </xsl:if> -->
</xsl:for-each>
</xsl:template>
</xsl:transform>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns:inventory="http://www.example.com/3"
xmlns:item="http://www.example.com/1">
<item:Milk contextRef="animals">12</item:Milk>
<item:Duck contextRef="animals">32</item:Duck>
<item:Beer contextRef="animals">8</item:Beer>
<item:Cow contextRef="animals">43</item:Cow>
</inventory>
想要的结果:
<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns:inventory="http://www.example.com/3"
xmlns:item="http://www.example.com/1">
<item:Milk contextRef="beverage">12</item:Milk>
<item:Duck contextRef="animals">32</item:Duck>
<item:Beer contextRef="beverage">8</item:Beer>
<item:Cow contextRef="animals">43</item:Cow>
</inventory>
我会将逗号分隔值标记为字符串序列,然后比较键,例如
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:item="http://www.example.com/1"
xmlns:inventory="http://www.example.com/2"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Categorization -->
<xsl:param name="group-animals">Cow, Duck</xsl:param>
<xsl:param name="animals" select="tokenize($group-animals, ',\s*')"/>
<xsl:param name="group-beverage">Milk, Beer</xsl:param>
<xsl:param name="beverages" select="tokenize($group-beverage, ',\s*')"/>
<!-- Variations of attribute settings -->
<xsl:attribute-set name="set-attributes-for-category-animals">
<xsl:attribute name="contextRef">animals</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="set-attributes-for-category-beverage">
<xsl:attribute name="contextRef">beverage</xsl:attribute>
</xsl:attribute-set>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<inventory>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</inventory>
</xsl:template>
<!-- Template -->
<!-- Planned logic: -->
<!--
If element defined in "group-animals" exist in JSON / XML map",
then use "set-attributes-for-category-animals"
If element defined in "group-beverage" exist in JSON / XML map",
then use "set-attributes-for-category-beverage"
-->
<xsl:template match="*[@key ='flat']/*[@key = $animals]">
<xsl:element
name="item:{@key}"
use-attribute-sets="set-attributes-for-category-animals">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="*[@key ='flat']/*[@key = $beverages]">
<xsl:element
name="item:{@key}"
use-attribute-sets="set-attributes-for-category-beverage">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:transform>
与例如=
是一种存在性比较,因此如果 key
属性的属性值等于字符串序列 $animals
中的至少一个字符串值,则 @key = $animals
为真。
整个匹配匹配具有 key
属性值 flat
的父元素的子元素,其中子元素的 key
值在 $animals
的序列中。
我正在使用一个平面 JSON 源文件,从分层树的角度来看。作为 XSLT 转换的一部分,我希望定义指示哪个元素应具有特定属性集的组。输出的元素顺序并不重要。
这是我的代码的最小化版本,所以我想将所有 settings/configuration/defitions 集中在 XSL 的顶部是有原因的。如果代码非常小,我认为直接在每个模板中添加请求的元素是有意义的。
我知道“if”元素行已被注释掉,可能需要使用正确的语法(和扩展)它们才能使解决方案起作用。
如果有另一种更好、更简单的定义组的方法也很好。
JSON:
<data>
{
"flat": {
"Milk": 12,
"Duck": 32,
"Beer": 8,
"Cow": 43
}
}
</data>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:item="http://www.example.com/1"
xmlns:inventory="http://www.example.com/2"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Categorization -->
<xsl:variable name="group-animals">Cow, Duck</xsl:variable>
<xsl:variable name="group-beverage">Milk, Beer</xsl:variable>
<!-- Variations of attribute settings -->
<xsl:attribute-set name="set-attributes-for-category-animals">
<xsl:attribute name="contextRef">animals</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="set-attributes-for-category-beverage">
<xsl:attribute name="contextRef">beverage</xsl:attribute>
</xsl:attribute-set>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<inventory>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</inventory>
</xsl:template>
<!-- Template -->
<!-- Planned logic: -->
<!--
If element defined in "group-animals" exist in JSON / XML map",
then use "set-attributes-for-category-animals"
If element defined in "group-beverage" exist in JSON / XML map",
then use "set-attributes-for-category-beverage"
-->
<xsl:template match="*[@key ='flat']">
<xsl:for-each select="*">
<!-- <xsl:if test=""> -->
<xsl:element
name="item:{@key}"
use-attribute-sets="set-attributes-for-category-animals"
>
<xsl:value-of select="text()"/>
</xsl:element>
<!-- </xsl:if> -->
</xsl:for-each>
</xsl:template>
</xsl:transform>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns:inventory="http://www.example.com/3"
xmlns:item="http://www.example.com/1">
<item:Milk contextRef="animals">12</item:Milk>
<item:Duck contextRef="animals">32</item:Duck>
<item:Beer contextRef="animals">8</item:Beer>
<item:Cow contextRef="animals">43</item:Cow>
</inventory>
想要的结果:
<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns:inventory="http://www.example.com/3"
xmlns:item="http://www.example.com/1">
<item:Milk contextRef="beverage">12</item:Milk>
<item:Duck contextRef="animals">32</item:Duck>
<item:Beer contextRef="beverage">8</item:Beer>
<item:Cow contextRef="animals">43</item:Cow>
</inventory>
我会将逗号分隔值标记为字符串序列,然后比较键,例如
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:item="http://www.example.com/1"
xmlns:inventory="http://www.example.com/2"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Categorization -->
<xsl:param name="group-animals">Cow, Duck</xsl:param>
<xsl:param name="animals" select="tokenize($group-animals, ',\s*')"/>
<xsl:param name="group-beverage">Milk, Beer</xsl:param>
<xsl:param name="beverages" select="tokenize($group-beverage, ',\s*')"/>
<!-- Variations of attribute settings -->
<xsl:attribute-set name="set-attributes-for-category-animals">
<xsl:attribute name="contextRef">animals</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="set-attributes-for-category-beverage">
<xsl:attribute name="contextRef">beverage</xsl:attribute>
</xsl:attribute-set>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<inventory>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</inventory>
</xsl:template>
<!-- Template -->
<!-- Planned logic: -->
<!--
If element defined in "group-animals" exist in JSON / XML map",
then use "set-attributes-for-category-animals"
If element defined in "group-beverage" exist in JSON / XML map",
then use "set-attributes-for-category-beverage"
-->
<xsl:template match="*[@key ='flat']/*[@key = $animals]">
<xsl:element
name="item:{@key}"
use-attribute-sets="set-attributes-for-category-animals">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="*[@key ='flat']/*[@key = $beverages]">
<xsl:element
name="item:{@key}"
use-attribute-sets="set-attributes-for-category-beverage">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:transform>
与例如=
是一种存在性比较,因此如果 key
属性的属性值等于字符串序列 $animals
中的至少一个字符串值,则 @key = $animals
为真。
整个匹配匹配具有 key
属性值 flat
的父元素的子元素,其中子元素的 key
值在 $animals
的序列中。