繁体   English   中英

XSLT2.0中的元素分组

[英]Grouping elements in XSLT2.0

对于以下XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bp_list xmlns="http://example.com/2012/03/01/canonical/somePartner">
<bp>
    <bp_id>1</bp_id>
    <bp_name>FirstName</bp_name>
    <last_changed_date>2016-12-06T18:27:20</last_changed_date>
    <department>
        <department_id>13</department_id>
        <department_name>SomeDepartment</department_name>
    </department>
    <location>
        <location_id>292300</location_id>
        <location_name>Country1</location_name>
        <is_location_owner>false</is_location_owner>
        <address>
            <id>333070831</id>
            <line1> </line1>
            <city>City1</city>
            <country_code>SC</country_code>
            <country_name>Country1</country_name>
            <subdivision_code>          </subdivision_code>
            <validation_status>107</validation_status>
        </address>
        <location_type>
            <location_type_id>510021</location_type_id>
            <location_type_name>store</location_type_name>
        </location_type>
        <location_capability>
            <location_capability_id>13</location_capability_id>
            <location_capability_name>SCton</location_capability_name>
            <location_capability_category>1</location_capability_category>
        </location_capability>
    </location>
    </bp>
<bp>
    <bp_id>3442</bp_id>
    <bp_name>SecondName</bp_name>
    <last_changed_date>2016-12-06T18:27:18</last_changed_date>
     <department>
        <department_id>1</department_id>
        <department_name>AnotherDepartment</department_name>
    </department>
    <location>
        <location_id>292300</location_id>
        <location_name>Country1</location_name>
        <address>
            <id>333070831</id>
            <line1> </line1>
            <city>City1</city>
            <country_code>SC</country_code>
            <country_name>Country1</country_name>
            <subdivision_code>          </subdivision_code>
            <validation_status>107</validation_status>
        </address>
        <location_type>
            <location_type_id>510021</location_type_id>
            <location_type_name>store</location_type_name>
        </location_type>
        <location_capability>
            <location_capability_id>13</location_capability_id>
            <location_capability_name>SCTon</location_capability_name>
            <location_capability_category>1</location_capability_category>
        </location_capability>
        </bp>

2个不同的bp_id(1和3442)具有相同的location_id(292300)。

我想要在csv中的如下输出:

bp_id,Location_id,location_name,location_type_name
1;3442,292300,Country1,store

据我了解,我基本上想对bp_ids进行分组。 这是我尝试的:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:ns="http://target.com/2012/03/01/canonical/BusinessPartner">
<xsl:strip-space elements="*"/>
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
    <xsl:for-each select="ns:bp_list/ns:bp/ns:location">
        <xsl:choose>
            <xsl:when
                test="ns:bp_location/ns:bp_location_capability/ns:is_primary_capability">
                <xsl:if
                    test="ns:bp_location/ns:bp_location_capability/ns:is_primary_capability/text() != 'true'"><xsl:for-each-group select="ancestor::ns:bp" group-by="ns:bp_id"><xsl:value-of select="ns:bp_id"/></xsl:for-each-group>|<xsl:value-of select="(ns:location_id)"/>|<xsl:value-of
                        select="(ns:location_name)"/>|<xsl:for-each
                            select="ns:location_type"><xsl:value-of
                                select="(ns:location_type_name)"/><xsl:if
                                    test="position() != last()"
                                    ><xsl:text>;</xsl:text></xsl:if></xsl:for-each>|<xsl:for-each select="(ns:bp_location/ns:bp_location_capability)"><xsl:value-of
                                        select="(ns:location_function_capability_name)"
                                    /><xsl:if
                                        test="position() != last()"
                                        ><xsl:text>;</xsl:text></xsl:if></xsl:for-each>|<xsl:value-of select="(ns:address/ns:city)"
                                        />|<xsl:value-of select="(ns:address/ns:subdivision_name)"
                                        />|<xsl:value-of select="(ns:address/ns:country_name)"
                                        />|<xsl:value-of select="(ns:location_status/ns:name)"
                                        /><xsl:text>&#10;</xsl:text>
                </xsl:if>
            </xsl:when>
            <xsl:otherwise> 
                <xsl:for-each-group select="ancestor::ns:bp" group-by="ns:bp_id"><xsl:value-of select="ns:bp_id"/></xsl:for-each-group>|<xsl:value-of select="(ns:location_id)"/>|<xsl:value-of
                    select="(ns:location_name)"/>|<xsl:for-each
                        select="ns:location_type"><xsl:value-of
                            select="(ns:location_type_name)"/><xsl:if
                                test="position() != last()"
                                ><xsl:text>;</xsl:text></xsl:if></xsl:for-each>|<xsl:for-each select="(ns:bp_location/ns:bp_location_capability)"><xsl:value-of
                                    select="(ns:location_function_capability_name)"
                                /><xsl:if
                                    test="position() != last()"
                                    ><xsl:text>;</xsl:text></xsl:if></xsl:for-each>|<xsl:value-of select="(ns:address/ns:city)"
                                    />|<xsl:value-of select="(ns:address/ns:subdivision_name)"
                                    />|<xsl:value-of select="(ns:address/ns:country_name)"
                                    />|<xsl:value-of select="(ns:location_status/ns:name)"
                                    /><xsl:text>&#10;</xsl:text>
            </xsl:otherwise>
        </xsl:choose> </xsl:for-each>
</xsl:template>

我正在尝试使用for-each-group,但没有得到理想的结果。 这就是我得到的。

bp_id,Location_id,location_name,location_type_name

1,292300,Country1,Store
3442,292300,Country1,Store

我必须使用ancestor,因为选择的过滤条件必须是第一个条件,然后才需要获取其余的列,因此我需要在XML工作表中来回移动。 其次,请忽略未提及的列的代码。 我对其余的数据都很满意。 我只停留在第一列中。 我正在使用XSLT 2.0。

我无法使用您的XSLT和XML示例获得任何信息。 XSLT有点tl; dr,所以我不会尝试尝试调试。 我看到一吨的| 而且没有逗号,所以我有一种感觉,如果它确实产生了输出,那将不会完全像您所描述的那样。

编辑:现在我看到您在样式表中为ns命名空间前缀只有一个不同的命名空间uri。

据我了解,我基本上想对bp_ids进行分组。

如果是我,我将在location_id分组。 我将为bp_id创建一个xsl:key ,这样我就不必使用ancestor::轴来返回树了。

例...

XML输入 (较小的错误,格式正确)

<bp_list xmlns="http://example.com/2012/03/01/canonical/somePartner">
    <bp>
        <bp_id>1</bp_id>
        <bp_name>FirstName</bp_name>
        <last_changed_date>2016-12-06T18:27:20</last_changed_date>
        <department>
            <department_id>13</department_id>
            <department_name>SomeDepartment</department_name>
        </department>
        <location>
            <location_id>292300</location_id>
            <location_name>Country1</location_name>
            <is_location_owner>false</is_location_owner>
            <address>                
                <id>333070831</id>
                <line1> </line1>
                <city>City1</city>
                <country_code>SC</country_code>
                <country_name>Country1</country_name>
                <subdivision_code>          </subdivision_code>
                <validation_status>107</validation_status>
            </address>
            <location_type>
                <location_type_id>510021</location_type_id>
                <location_type_name>store</location_type_name>
            </location_type>
            <location_capability>
                <location_capability_id>13</location_capability_id>
                <location_capability_name>SCton</location_capability_name>
                <location_capability_category>1</location_capability_category>
            </location_capability>
        </location>
    </bp>
    <bp>
        <bp_id>3442</bp_id>
        <bp_name>SecondName</bp_name>
        <last_changed_date>2016-12-06T18:27:18</last_changed_date>
        <department>
            <department_id>1</department_id>
            <department_name>AnotherDepartment</department_name>
        </department>
        <location>
            <location_id>292300</location_id>
            <location_name>Country1</location_name>
            <address>
                <id>333070831</id>
                <line1> </line1>
                <city>City1</city>
                <country_code>SC</country_code>
                <country_name>Country1</country_name>
                <subdivision_code>          </subdivision_code>
                <validation_status>107</validation_status>
            </address>
            <location_type>
                <location_type_id>510021</location_type_id>
                <location_type_name>store</location_type_name>
            </location_type>
            <location_capability>
                <location_capability_id>13</location_capability_id>
                <location_capability_name>SCTon</location_capability_name>
                <location_capability_category>1</location_capability_category>
            </location_capability>
        </location>
    </bp>
</bp_list>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xpath-default-namespace="http://example.com/2012/03/01/canonical/somePartner">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="bpid" match="bp" use="location/location_id"/>

  <xsl:template match="/bp_list">
    <xsl:text>bp_id,Location_id,location_name,location_type_name&#xA;</xsl:text>
    <xsl:for-each-group select="bp/location" group-by="location_id">
      <xsl:value-of select="string-join(key('bpid',current-grouping-key())/bp_id,';')"/>
      <xsl:text>,</xsl:text>
      <xsl:for-each select="current-group()[1]">
        <xsl:value-of select="string-join((location_id,location_name,
          location_type/location_type_name),',')"/>
      </xsl:for-each>
      <xsl:text>&#xA;</xsl:text>
    </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>

产量

bp_id,Location_id,location_name,location_type_name
1;3442,292300,Country1,store

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM