【问题标题】:Grouping elements in XSLT2.0XSLT 2.0 中的分组元素
【发布时间】:2017-02-28 17:47:41
【问题描述】:

对于以下 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

我必须使用祖先,因为选择下的过滤条件必须是第一个条件,然后才能获得其余列。所以我需要在 XML 表中来回移动。其次,请忽略未提及的列的代码。我对其余的数据很好。我只被困在第一列。我正在使用 XSLT 2.0。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    我无法使用您的 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
    

    【讨论】:

      猜你喜欢
      • 2011-07-02
      • 2016-02-22
      • 1970-01-01
      • 2014-05-13
      • 2022-01-12
      • 1970-01-01
      • 2011-08-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多