XML - XSLT 元素列表 - 连接具有相同属性值的元素

名字

我正在尝试生成具有特定结构的 XML 文件,但我被卡住了,

这是我的输入 XML 文件:

    <report>
    <page name="Simple MasterPage">
        <table id="__bookmark_1">
            <table-band band-type="BAND_HEADER">
                <row>
                    <cell>
                        <label>PERSONNAME</label>
                    </cell>
                    <cell>
                        <label>PERSONID</label>
                    </cell>
                    <cell>
                        <label>NUMELEM</label>
                    </cell>
                    <cell>
                        <label>CREATIONDATE</label>
                    </cell>
<cell>
                        <label>CREATIONDATE</label>
                    </cell>
                </row>
            </table-band>
            <table-band band-type="BAND_DETAIL">
                <row>
                    <cell>
                        <data>John</data>
                    </cell>
                    <cell>
                        <data>p1</data>
                    </cell>
                    <cell>
                        <data>1</data>
                    </cell>
                    <cell>
                        <data>2018-06-21</data>
                    </cell>
                </row>
            </table-band>
            <table-band band-type="BAND_DETAIL">
                <row>
                    <cell>
                        <data>John</data>
                    </cell>
                    <cell>
                        <data>p1</data>
                    </cell>
                    <cell>
                        <data>2</data>
                    </cell>
                    <cell>
                        <data>2018-06-21</data>
                    </cell>
                </row>
            </table-band>
            <table-band band-type="BAND_DETAIL">
                <row>
                    <cell>
                        <data>John</data>
                    </cell>
                    <cell>
                        <data>p1</data>
                    </cell>
                    <cell>
                        <data>3</data>
                    </cell>
                    <cell>
                        <data>2018-06-21</data>
                    </cell>
                </row>
            </table-band>
            <table-band band-type="BAND_DETAIL">
                <row>
                    <cell>
                        <data>John</data>
                    </cell>
                    <cell>
                        <data>p1</data>
                    </cell>
                    <cell>
                        <data>4</data>
                    </cell>
                    <cell>
                        <data>2018-06-21</data>
                    </cell>
                </row>
            </table-band>
            <table-band band-type="BAND_DETAIL">
                <row>
                    <cell>
                        <data>John</data>
                    </cell>
                    <cell>
                        <data>p1</data>
                    </cell>
                    <cell>
                        <data>5</data>
                    </cell>
                    <cell>
                        <data>2018-06-21</data>
                    </cell>
                </row>
            </table-band>
            <table-band band-type="BAND_DETAIL">
                <row>
                    <cell>
                        <data>Marie</data>
                    </cell>
                    <cell>
                        <data>p2</data>
                    </cell>
                    <cell>
                        <data>6</data>
                    </cell>
                    <cell>
                        <data>2018-06-21</data>
                    </cell>
                </row>
            </table-band>
            <table-band band-type="BAND_DETAIL">
                <row>
                    <cell>
                        <data>Marie</data>
                    </cell>
                    <cell>
                        <data>p2</data>
                    </cell>
                    <cell>
                        <data>7</data>
                    </cell>
                    <cell>
                        <data>2018-06-21</data>
                    </cell>
                </row>
            </table-band>
        </table>
    </page>
</report>

这是我用来转换它的 XSLT,用户 @Parfait 教我如何在一个非常相似的帖子上构建:

    <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" omit-xml-declaration="no" encoding="utf-8"/>
    <xsl:strip-space elements="*"/>


    <xsl:template match="/report/page/table">
     <entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versao="1.0">
            <!--Para comecar da 2 tabela-->
            <xsl:apply-templates select="table-band[position() &gt; 1] "/>
     </entry> 
    </xsl:template>

    <xsl:template name="top_build-attrib">
      <xsl:param name="label_val"/>
      <xsl:param name="attrib_nm"/>
       <xsl:variable name="row_num" select="count(table-band[1]/row/cell[label=$label_val]/preceding-sibling::*)+1"/>
       <xsl:attribute name="{$attrib_nm}"><xsl:value-of select="table-band[2]/row/cell[position()=$row_num]/data"/></xsl:attribute>
    </xsl:template>

    <xsl:template name="build-attrib">
      <xsl:param name="label_val"/>
      <xsl:param name="attrib_nm"/>
       <xsl:variable name="row_num" select="count(ancestor::table/table-band[1]/row/cell[label=$label_val]/preceding-sibling::*)+1"/>
       <xsl:attribute name="{$attrib_nm}"><xsl:value-of select="row/cell[position()=$row_num]/data"/></xsl:attribute>
    </xsl:template>


    <xsl:template name="elem_value">
      <xsl:param name="label_val"/>
       <xsl:variable name="row_num" select="count(ancestor::table/table-band[1]/row/cell[label=$label_val]/preceding-sibling::*)+1"/>
       <xsl:value-of select="row/cell[position()=$row_num]/data"/>
    </xsl:template>

    <xsl:template match="table-band">

            <person>
                <xsl:call-template name="build-attrib">
                   <xsl:with-param name="label_val">PERSONNAME</xsl:with-param>
                   <xsl:with-param name="attrib_nm">personName</xsl:with-param>
                </xsl:call-template>

                <xsl:call-template name="build-attrib">
                   <xsl:with-param name="label_val">PERSONID</xsl:with-param>
                   <xsl:with-param name="attrib_nm">personID</xsl:with-param>
                </xsl:call-template>

                <listOfElements>
                    <element>
                        <xsl:call-template name="build-attrib">
                            <xsl:with-param name="label_val">NUMELEM</xsl:with-param>
                            <xsl:with-param name="attrib_nm">numElem</xsl:with-param>
                        </xsl:call-template>
                        <xsl:call-template name="build-attrib">
                            <xsl:with-param name="label_val">CREATIONDATE</xsl:with-param>
                            <xsl:with-param name="attrib_nm">creationDate</xsl:with-param>
                        </xsl:call-template>
                   </element>
                </listOfElements>
            </person> 
    </xsl:template>

    </xsl:stylesheet>

这是我得到的结果:

    <?xml version="1.0" encoding="UTF-8"?>
      <entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versao="1.0">
        <person personID="p1" personName="John">
         <listOfElements>
            <element creationDate="2018-06-21" numElem="1"/>
         </listOfElements>
        </person>
        <person personID="p1" personName="John">
          <listOfElements>
            <element creationDate="2018-06-21" numElem="2"/>
          </listOfElements>
        </person>
        <person personID="p1" personName="John">
          <listOfElements>
            <element creationDate="2018-06-21" numElem="3"/>
          </listOfElements>
        </person>
        <person personID="p1" personName="John">
          <listOfElements>
            <element creationDate="2018-06-21" numElem="4"/>
          </listOfElements>
        </person>
        <person personID="p1" personName="John">
          <listOfElements>
            <element creationDate="2018-06-21" numElem="5"/>
          </listOfElements>
        </person>
        <person personID="p2" personName="Marie">
          <listOfElements>
            <element creationDate="2018-06-21" numElem="6"/>
          </listOfElements>
        </person>
        <person personID="p2" personName="Marie">
          <listOfElements>
            <element creationDate="2018-06-21" numElem="7"/>
          </listOfElements>
        </person>
     </entry>

但是我正在寻找并且需要 prodocue 的结果是这个:

    <?xml version="1.0" encoding="utf-8"?>
     <entry>
       <person personID="p1" personName="John">
        <listOfElements>
            <element creationDate="2018-06-21" numElem="1" />
            <element creationDate="2018-06-21" numElem="2" />
            <element creationDate="2018-06-21" numElem="3" />
            <element creationDate="2018-06-21" numElem="4" />
            <element creationDate="2018-06-21" numElem="5"/>
        </listOfElements>
       </person>
       <person personID="p2" personName="Marie">
        <listOfElements>
            <element creationDate="2018-06-21" numElem="6" />
            <element creationDate="2018-06-21" numElem="7" />
        </listOfElements>
       </person>
    </entry>

这意味着我无法listOfElements像我应该那样生成,我正在打印一个新person节点而不是“加入”element同一person节点中的节点(在listOfElements节点内部

我知道解决方案必须与比较presonIDpersonName属性有关,但我只是没有到达那里......

我真的需要一些帮助伙计们,谢谢!

编辑

我尝试xsl:for-each-group在每个element标签之前添加,但我仍然得到相同的结果。做了以下事情:

               <listOfElements>
                    <xsl:for-each-group select="table-band[@band-type='BAND_DETAIL']/row" group-by="cell[2]/data">
                    <element>
                        <xsl:call-template name="build-attrib">
                            <xsl:with-param name="label_val">NUMELEM</xsl:with-param>
                            <xsl:with-param name="attrib_nm">numElem</xsl:with-param>
                        </xsl:call-template>
                        <xsl:call-template name="build-attrib">
                            <xsl:with-param name="label_val">CREATIONDATE</xsl:with-param>
                            <xsl:with-param name="attrib_nm">creationDate</xsl:with-param>
                        </xsl:call-template>
                   </element>
                   </xsl:for-each-group>
                </listOfElements>

编辑我更改了输入xml和输出,这意味着输入xml丢失了NUMDOC和CREATIONDATE元素,并获得了一个新的ELEMENTTYPE,

所以,我失去了在内部使用的分组因子我for-each-group,那是NUMDOC,像@Parfait TEACHED我。现在我不知道如何只使用ELEMENTTYPE. 请注意,我希望能够为同一个人拥有相同的不同元素ELEMENTTYPE,所以这不能用于 中的因素for-each-group,或者可以吗?

输入 XML:(更新)

    <report>
        <page name="Simple MasterPage">
            <table id="__bookmark_1">
                <table-band band-type="BAND_HEADER">
                    <row>
                        <cell>
                            <label>PERSONNAME</label>
                        </cell>
                        <cell>
                            <label>PERSONID</label>
                        </cell>
                        <cell>
                            <label>ELEMENTTYPE</label>
                        </cell>
                    </row>
                </table-band>
                <table-band band-type="BAND_DETAIL">
                    <row>
                        <cell>
                            <data>John</data>
                        </cell>
                        <cell>
                            <data>p1</data>
                        </cell>
                        <cell>
                            <data>001</data>
                        </cell>
                    </row>
                </table-band>
                <table-band band-type="BAND_DETAIL">
                    <row>
                        <cell>
                            <data>John</data>
                        </cell>
                        <cell>
                            <data>p1</data>
                        </cell>
                        <cell>
                            <data>001</data>
                        </cell>
                    </row>
                </table-band>
                <table-band band-type="BAND_DETAIL">
                    <row>
                        <cell>
                            <data>John</data>
                        </cell>
                        <cell>
                            <data>p1</data>
                        </cell>
                        <cell>
                            <data>002</data>
                        </cell>
                    </row>
                </table-band>
                <table-band band-type="BAND_DETAIL">
                    <row>
                        <cell>
                            <data>John</data>
                        </cell>
                        <cell>
                            <data>p1</data>
                        </cell>
                        <cell>
                            <data>001</data>
                        </cell>
                    </row>
                </table-band>
                <table-band band-type="BAND_DETAIL">
                    <row>
                        <cell>
                            <data>John</data>
                        </cell>
                        <cell>
                            <data>p1</data>
                        </cell>
                        <cell>
                            <data>002</data>
                        </cell>
                    </row>
                </table-band>
                <table-band band-type="BAND_DETAIL">
                    <row>
                        <cell>
                            <data>Marie</data>
                        </cell>
                        <cell>
                            <data>p2</data>
                        </cell>
                        <cell>
                            <data>001</data>
                        </cell>
                    </row>
                </table-band>
                <table-band band-type="BAND_DETAIL">
                    <row>
                        <cell>
                            <data>Marie</data>
                        </cell>
                        <cell>
                            <data>p2</data>
                        </cell>
                        <cell>
                            <data>001</data>
                        </cell>
                    </row>
                </table-band>
            </table>
        </page>
    </report>

所以我想得到的输出是:

    <?xml version="1.0" encoding="utf-8"?>
         <entry>
           <person personID="p1" personName="John">
            <listOfElements>
                <element elementType="001" />
                <element elementType="001" />
                <element elementType="002" />
                <element elementType="001" />
                <element elementType="002" />
            </listOfElements>
           </person>
           <person personID="p2" personName="Marie">
            <listOfElements>
                <element elementType="001" />
                <element elementType="001" />
            </listOfElements>
           </person>
        </entry>

我不知道在内部使用什么for-each-group,之前,就像@Parfait 向我展示的那样,我使用了NUMDOC,但现在我没有任何东西可以区分文档!

谢谢!

亚历山大·哈辛托

完美的

考虑<xsl:for-each-group>在当前 XSLT 的最后一个模板中应用两层,指向first 中PERSONNAMENUMELEM对应位置<table-band>

XSLT 小提琴演示

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8"/>
   <xsl:strip-space elements="*"/>

   <xsl:template match="/report/page">
      <entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versao="1.0">
        <!--Para comecar da 2 tabela-->
        <xsl:apply-templates select="table"/>
      </entry> 
   </xsl:template>

   <xsl:template name="top_build-attrib">
     <xsl:param name="label_val"/>
     <xsl:param name="attrib_nm"/>
      <xsl:variable name="row_num" select="count(table-band[1]/row/cell[label=$label_val]/preceding-sibling::*)+1"/>
      <xsl:attribute name="{$attrib_nm}"><xsl:value-of select="table-band[2]/row/cell[position()=$row_num]/data"/></xsl:attribute>
   </xsl:template>

   <xsl:template name="build-attrib">
     <xsl:param name="label_val"/>
     <xsl:param name="attrib_nm"/>
      <xsl:variable name="row_num" select="count(ancestor::table/table-band[1]/row/cell[label=$label_val]/preceding-sibling::*)+1"/>
      <xsl:attribute name="{$attrib_nm}"><xsl:value-of select="row/cell[position()=$row_num]/data"/></xsl:attribute>
   </xsl:template>

   <xsl:template name="elem_value">
     <xsl:param name="label_val"/>
      <xsl:variable name="row_num" select="count(ancestor::table/table-band[1]/row/cell[label=$label_val]/preceding-sibling::*)+1"/>
      <xsl:value-of select="row/cell[position()=$row_num]/data"/>
   </xsl:template>

   <xsl:template match="table">

       <xsl:for-each-group select="table-band" group-by="row/cell[position()=
                      count(ancestor::table/table-band[1]/row/cell[label='PERSONNAME']/preceding-sibling::*)+1]/data">
         <person>
            <xsl:call-template name="build-attrib">
               <xsl:with-param name="label_val">PERSONID</xsl:with-param>
               <xsl:with-param name="attrib_nm">personID</xsl:with-param>
            </xsl:call-template>

            <xsl:call-template name="build-attrib">
               <xsl:with-param name="label_val">PERSONNAME</xsl:with-param>
               <xsl:with-param name="attrib_nm">personName</xsl:with-param>
            </xsl:call-template>

            <listOfElements>
                <xsl:for-each-group select="current-group()" group-by="row/cell[position()=
                      count(ancestor::table/table-band[1]/row/cell[label='NUMELEM']/preceding-sibling::*)+1]">
                    <element>
                        <xsl:call-template name="build-attrib">
                            <xsl:with-param name="label_val">NUMELEM</xsl:with-param>
                            <xsl:with-param name="attrib_nm">numElem</xsl:with-param>
                        </xsl:call-template>
                        <xsl:call-template name="build-attrib">
                            <xsl:with-param name="label_val">CREATIONDATE</xsl:with-param>
                            <xsl:with-param name="attrib_nm">creationDate</xsl:with-param>
                        </xsl:call-template>
                   </element>
                </xsl:for-each-group>
            </listOfElements>
        </person> 

       </xsl:for-each-group>
   </xsl:template>

</xsl:stylesheet>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

反序列化具有相同属性的xml元素

来自分类Dev

不同元素中相同属性的XML值不能重复

来自分类Dev

如何使用xslt将元素的列表类型重构为xml

来自分类Dev

XSLT更改XML元素顺序

来自分类Dev

xml使用xslt删除元素

来自分类Dev

使用 XSLT 映射 XML 元素

来自分类Dev

使用XSLT基于属性合并Xml元素

来自分类Dev

使用XSLT基于属性合并Xml元素

来自分类Dev

合并具有相同属性的元素

来自分类Dev

XSLT通过元素匹配从xml复制元素

来自分类Dev

使用XSLT更改xml文件中文档元素的属性值

来自分类Dev

使用xslt使用属性值替换XML元素标签

来自分类Dev

使用XSLT查找具有可变/变化位置的XML元素

来自分类Dev

如何创建仅从 XML 中删除其属性值包含在 XPATH 选定值列表中的那些元素的 XSLT

来自分类Dev

使用XSLT从XML创建XML-播放所有元素

来自分类Dev

XSLT转换,用逗号分隔xml元素

来自分类Dev

使用XSLT递归删除空的xml元素

来自分类Dev

XSLT转换,用逗号分隔xml元素

来自分类Dev

XSLT无法获取xml子元素

来自分类Dev

使用XSLT递归删除空的xml元素

来自分类Dev

使用XSLT添加新的XML元素

来自分类Dev

如何使用xslt转换嵌套的XML元素?

来自分类Dev

更改重复的元素名称 xslt xml

来自分类Dev

使用 XSLT 更改 XML 元素标记

来自分类Dev

如何使用 xslt 移动 xml 元素?

来自分类Dev

如何使用LINQ to XML连接具有相同名称值的所有子元素

来自分类Dev

XSLT:删除具有重复属性值的元素

来自分类Dev

XSLT使用XSLT从xml中删除一个根元素的所有属性

来自分类Dev

使用xslt将子元素添加到xml中的列表中不起作用