基于key的XSL构建节点
XSL build node based on key
输入:
<?xml version="1.0" encoding="UTF-8"?>
<comtec>
<record id="1">
<column name="id_task">44422</column>
<column name="capabilityCode">FR-JUNIOR</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867139</column>
</record>
<record id="2">
<column name="id_task">44422</column>
<column name="capabilityCode">FR-XXX</column>
<column name="ColMiss"/>
<column name="ColHave">notmiss</column>
<column name="order_externalId">1867139</column>
</record>
<record id="3">
<column name="id_task">44422</column>
<column name="capabilityCode">AVS</column>
<column name="ColMiss"/>
<column name="ColHave">notmiss</column>
<column name="order_externalId">1867139</column>
</record>
<record id="4">
<column name="id_task">60038</column>
<column name="PropertyDescr">ReqMissing</column>
<column name="capabilityCode">FR-AUTOPLAN</column>
<column name="ResCapString">FR-RDV1, FR-GGE1, FR-PARC2, FR-RDV VIP</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867454</column>
</record>
<record id="5">
<column name="id_task">60038</column>
<column name="capabilityCode">FR-XXX</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867454</column>
</record>
</comtec>
期望的输出:
<comtec>
<task_order>
<id>1867139</id>
<capabilities>
<capability>
<capability_code>FR-JUNIOR</capability_code>
<available>true</available>
</capability>
<capability>
<capability_code>FR-XXX</capability_code>
<required>true</required>
</capability>
<capability>
<capability_code>AVS</capability_code>
<required>true</required>
</capability>
</capabilities>
<task>
<id>1867139</id>
<task_kind_code>drive_through</task_kind_code>
</task>
</task_order>
<task_order>
<id>1867454</id>
<capabilities>
<capability>
<capability_code>FR-AUTOPLAN</capability_code>
<available>true</available>
</capability>
<capability>
<capability_code>FR-XXX</capability_code>
<available>true</available>
</capability>
</capabilities>
<task>
<id>1867454</id>
<task_kind_code>drive_through</task_kind_code>
</task>
</task_order>
</comtec>
您好。所需的输出基于以下逻辑:
id_task有多条记录
a) 如果 'ColMiss' 列中只有值,则构建空的能力标签(输出中的第二个记录标签)
b) 如果它在 'ColMiss' 列和 'ColHave' 中都有值,则仅使用 'ColHave' 不为空的记录中 'CapabilityCode' 列的值构建功能标记。
我希望它有意义,我仍然是 XSL keys/var 部分的新手,我正在研究一些例子来理解。
谢谢
更新:
当前 XSL - 没有 keys/variables
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:key name="record" match="record" use="record/column[@name='id_task']"/>
<xsl:template match="comtec">
<!--grouped by id_task-->
<xsl:for-each select="record[generate-id(.)=
generate-id(key('record',
record/column[@name='id_task'])[1])]">
<task_order>
<id>
<xsl:value-of select="column[@name='id_task']"/>
</id>
<capabilities>
<!--the fields in capabilities-->
<xsl:variable name="values" select="key('record',
column[@name='id_task'])/
column[@name='ColMiss']"/>
<xsl:choose>
<xsl:when test="$values ='miss'">
<xsl:for-each select="$values ='miss'">
<capability>
<capability_code>
<xsl:value-of select="column[name='capabilityCode']"/>
</capability_code>
<available>true</available>
</capability>
</xsl:for-each>
</xsl:when>
<xsl:when test="$values =''">
<xsl:for-each select="$values =''">
<capability>
<capability_code>
<xsl:value-of select="column[name='capabilityCode']"/>
</capability_code>
<required>true</required>
</capability>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</capabilities>
</task_order>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
如您所见,问题在于它不会将 'capability' 标签分组到一个父标签下,而是会为每个记录创建一个标签,这是正常的,因为实现了逻辑。
但我认为除了使用 key/variable.
之外还有其他方法
基于这个 XSL 有没有办法得到想要的输出?
再次感谢。
我无法完全理解你的逻辑,但你遇到的第一个问题是你如何定义你的密钥
<xsl:key name="record" match="record" use="record/column[@name='id_task']"/>
这将查找 record
元素,方法是查找它们的子 record
元素,这些元素与您的 XML 中的元素不匹配。应该是这个...
<xsl:key name="record" match="record" use="column[@name='id_task']"/>
同样,当您在 Muenchian 分组中使用此键时...
<xsl:for-each select="record[generate-id(.)=generate-id(key('record', column[@name='id_task'])[1])]">
你的xsl:for-each
也有问题...
<xsl:for-each select="$values ='miss'">
这是无效的,因为 $values ='miss'
的结果是 "true" 或 "false",并且 xsl:for-each
需要选择节点,而不是布尔值。
无论如何,试试这个 XSLT。它不会给你你需要的结果,因为我可以完全理解你的确切逻辑,但它可能会给你一个更好的起点......
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="record" match="record" use="column[@name='id_task']"/>
<xsl:template match="comtec">
<!--grouped by id_task-->
<xsl:for-each select="record[generate-id(.)=generate-id(key('record', column[@name='id_task'])[1])]">
<task_order>
<id>
<xsl:value-of select="column[@name='id_task']"/>
</id>
<capabilities>
<!--the fields in capabilities-->
<xsl:variable name="values" select="key('record',column[@name='id_task'])/column[@name='ColMiss']"/>
<xsl:for-each select="key('record',column[@name='id_task'])">
<capability>
<capability_code>
<xsl:value-of select="column[@name='capabilityCode']"/>
</capability_code>
<xsl:choose>
<xsl:when test="$values[. ='miss']">
<required>true</required>
</xsl:when>
<xsl:otherwise>
<available>true</available>
</xsl:otherwise>
</xsl:choose>
</capability>
</xsl:for-each>
</capabilities>
</task_order>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
请注意,如 $values[. ='']
这样的表达式,如果任何值都为空,则不一定全部为空。如果你想测试所有的空白,你必须做 not($values[. != ''])
(即不存在一个不是空白的)。
输入:
<?xml version="1.0" encoding="UTF-8"?>
<comtec>
<record id="1">
<column name="id_task">44422</column>
<column name="capabilityCode">FR-JUNIOR</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867139</column>
</record>
<record id="2">
<column name="id_task">44422</column>
<column name="capabilityCode">FR-XXX</column>
<column name="ColMiss"/>
<column name="ColHave">notmiss</column>
<column name="order_externalId">1867139</column>
</record>
<record id="3">
<column name="id_task">44422</column>
<column name="capabilityCode">AVS</column>
<column name="ColMiss"/>
<column name="ColHave">notmiss</column>
<column name="order_externalId">1867139</column>
</record>
<record id="4">
<column name="id_task">60038</column>
<column name="PropertyDescr">ReqMissing</column>
<column name="capabilityCode">FR-AUTOPLAN</column>
<column name="ResCapString">FR-RDV1, FR-GGE1, FR-PARC2, FR-RDV VIP</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867454</column>
</record>
<record id="5">
<column name="id_task">60038</column>
<column name="capabilityCode">FR-XXX</column>
<column name="ColMiss">miss</column>
<column name="ColHave"/>
<column name="order_externalId">1867454</column>
</record>
</comtec>
期望的输出:
<comtec>
<task_order>
<id>1867139</id>
<capabilities>
<capability>
<capability_code>FR-JUNIOR</capability_code>
<available>true</available>
</capability>
<capability>
<capability_code>FR-XXX</capability_code>
<required>true</required>
</capability>
<capability>
<capability_code>AVS</capability_code>
<required>true</required>
</capability>
</capabilities>
<task>
<id>1867139</id>
<task_kind_code>drive_through</task_kind_code>
</task>
</task_order>
<task_order>
<id>1867454</id>
<capabilities>
<capability>
<capability_code>FR-AUTOPLAN</capability_code>
<available>true</available>
</capability>
<capability>
<capability_code>FR-XXX</capability_code>
<available>true</available>
</capability>
</capabilities>
<task>
<id>1867454</id>
<task_kind_code>drive_through</task_kind_code>
</task>
</task_order>
</comtec>
您好。所需的输出基于以下逻辑: id_task有多条记录 a) 如果 'ColMiss' 列中只有值,则构建空的能力标签(输出中的第二个记录标签) b) 如果它在 'ColMiss' 列和 'ColHave' 中都有值,则仅使用 'ColHave' 不为空的记录中 'CapabilityCode' 列的值构建功能标记。
我希望它有意义,我仍然是 XSL keys/var 部分的新手,我正在研究一些例子来理解。
谢谢
更新:
当前 XSL - 没有 keys/variables
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:key name="record" match="record" use="record/column[@name='id_task']"/>
<xsl:template match="comtec">
<!--grouped by id_task-->
<xsl:for-each select="record[generate-id(.)=
generate-id(key('record',
record/column[@name='id_task'])[1])]">
<task_order>
<id>
<xsl:value-of select="column[@name='id_task']"/>
</id>
<capabilities>
<!--the fields in capabilities-->
<xsl:variable name="values" select="key('record',
column[@name='id_task'])/
column[@name='ColMiss']"/>
<xsl:choose>
<xsl:when test="$values ='miss'">
<xsl:for-each select="$values ='miss'">
<capability>
<capability_code>
<xsl:value-of select="column[name='capabilityCode']"/>
</capability_code>
<available>true</available>
</capability>
</xsl:for-each>
</xsl:when>
<xsl:when test="$values =''">
<xsl:for-each select="$values =''">
<capability>
<capability_code>
<xsl:value-of select="column[name='capabilityCode']"/>
</capability_code>
<required>true</required>
</capability>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</capabilities>
</task_order>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
如您所见,问题在于它不会将 'capability' 标签分组到一个父标签下,而是会为每个记录创建一个标签,这是正常的,因为实现了逻辑。 但我认为除了使用 key/variable.
之外还有其他方法基于这个 XSL 有没有办法得到想要的输出?
再次感谢。
我无法完全理解你的逻辑,但你遇到的第一个问题是你如何定义你的密钥
<xsl:key name="record" match="record" use="record/column[@name='id_task']"/>
这将查找 record
元素,方法是查找它们的子 record
元素,这些元素与您的 XML 中的元素不匹配。应该是这个...
<xsl:key name="record" match="record" use="column[@name='id_task']"/>
同样,当您在 Muenchian 分组中使用此键时...
<xsl:for-each select="record[generate-id(.)=generate-id(key('record', column[@name='id_task'])[1])]">
你的xsl:for-each
也有问题...
<xsl:for-each select="$values ='miss'">
这是无效的,因为 $values ='miss'
的结果是 "true" 或 "false",并且 xsl:for-each
需要选择节点,而不是布尔值。
无论如何,试试这个 XSLT。它不会给你你需要的结果,因为我可以完全理解你的确切逻辑,但它可能会给你一个更好的起点......
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="record" match="record" use="column[@name='id_task']"/>
<xsl:template match="comtec">
<!--grouped by id_task-->
<xsl:for-each select="record[generate-id(.)=generate-id(key('record', column[@name='id_task'])[1])]">
<task_order>
<id>
<xsl:value-of select="column[@name='id_task']"/>
</id>
<capabilities>
<!--the fields in capabilities-->
<xsl:variable name="values" select="key('record',column[@name='id_task'])/column[@name='ColMiss']"/>
<xsl:for-each select="key('record',column[@name='id_task'])">
<capability>
<capability_code>
<xsl:value-of select="column[@name='capabilityCode']"/>
</capability_code>
<xsl:choose>
<xsl:when test="$values[. ='miss']">
<required>true</required>
</xsl:when>
<xsl:otherwise>
<available>true</available>
</xsl:otherwise>
</xsl:choose>
</capability>
</xsl:for-each>
</capabilities>
</task_order>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
请注意,如 $values[. ='']
这样的表达式,如果任何值都为空,则不一定全部为空。如果你想测试所有的空白,你必须做 not($values[. != ''])
(即不存在一个不是空白的)。