基于密钥的XSL构建节点

时间:2017-02-02 17:01:22

标签: xml xslt xslkey

INPUT:

<?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的键/ var部分的新手,我正在研究一些例子来理解。

谢谢

更新:

当前XSL - 没有键/变量

   <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'标记分组在一个父级下,但它会创建一个每个记录标记,由于实现了逻辑,这是正常的。 但我认为除了使用键/变量之外还有其他一些方法。

基于这个XSL有没有办法转到所需的输出?

再次感谢你。

1 个答案:

答案 0 :(得分:0)

我无法完全弄清楚你的逻辑,但你遇到的第一个问题是如何定义你的密钥

<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[. != ''])(即不存在非空白的那个)。