我试图生成具有特定结构的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() > 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>
但是我要寻找的结果是要执行此操作的:
<?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
节点内部)
我知道解决方案必须与比较presonID
或personName
属性有关,但我只是没有到达...
我真的需要一些帮助人员,谢谢!
编辑
我尝试在每个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教给我的那样。现在,我不知道如何仅使用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
,但是现在我没有什么可区分文档了!
谢谢!
Alexandre Jacinto
答案 0 :(得分:0)
下面是一个最小的样式表,其中包含了我在评论中提出的建议(已将分组键调整为从第二个单元格获取数据值)
<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 indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/report/page/table">
<entry versao="1.0">
<xsl:for-each-group select="table-band[@band-type='BAND_DETAIL']/row" group-by="cell[2]/data">
<person personID="{current-grouping-key()}" personName="{cell[1]/data}">
<listOfElements>
<xsl:apply-templates select="current-group()"/>
</listOfElements>
</person>
</xsl:for-each-group>
</entry>
</xsl:template>
<xsl:template match="row">
<element creationDate="{cell[4]/data}" numElem="{cell[3]/data}"/>
</xsl:template>
</xsl:stylesheet>
在https://xsltfiddle.liberty-development.net/bdxtq7使用Saxon 9.8 HE的样品的结果为
<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"/>
<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>
答案 1 :(得分:0)
请考虑在当前XSLT的最后一个模板中应用两层<xsl:for-each-group>
,指向在第一个{{1}中的 PERSONNAME 和 NUMELEM 对应的位置}:
<table-band>