SubGroup in xslt with mutiple keys

为君一笑 提交于 2020-06-17 11:07:18

问题


I have a source xml like below. Im trying to convert to a desired format using xslt as shown below.

Sample XML

<table>
    <row>
        <tablename>table1</tablename>
        <tableDesc>table1_desc</tableDesc>
        <columnname>col1</columnname>
        <columnDesc>col1_desc</columnDesc>
        <columnDataType>Number</columnDataType>
        <ultimateSourceTable>sourceTable1</ultimateSourceTable>
        <ultimateSourceTableDesc>col1sourceTable1_desc</ultimateSourceTableDesc>
    </row>
    <row>
        <tablename>table1</tablename>
        <tableDesc>table1_desc</tableDesc>
        <columnname>col1</columnname>
        <columnDesc>col1_desc</columnDesc>
        <columnDataType>Number</columnDataType>
        <ultimateSourceTable>sourceTable2</ultimateSourceTable>
        <ultimateSourceTableDesc>col1sourceTable2_desc</ultimateSourceTableDesc>
    </row>
    <row>
        <tablename>table2</tablename>
        <tableDesc>table2_desc</tableDesc>
        <columnname>table2_col1</columnname>
        <columnDesc>table2_col1_desc</columnDesc>
        <columnDataType>String</columnDataType>
        <ultimateSourceTable>sourceTable2</ultimateSourceTable>
        <ultimateSourceTableDesc>col1sourceTable2_desc</ultimateSourceTableDesc>
    </row>
</table> 

Desired Output

<Prod>
        <dataBase>
            <physicalTableName>
                <tableName>table1</tableName>
                <tableDescription>table1_desc</tableDescription>
            </physicalTableName>
            <columnList>
                <column>
                <name>col1</name>
                <columnDesc>col1_desc</columnDesc>
                <columnDataType>Number</columnDataType>
                </column>
            </columnList>
            <finalSourceList>
                <column>
                    <columnName>col1</columnName>
                    <ultimateSourceTable>sourceTable1</ultimateSourceTable>
                    <ultimateSourceTableDesc>col1sourceTable1_desc</ultimateSourceTableDesc>
                </column>
                <column>
                    <columnName>col1</columnName>
                    <ultimateSourceTable>sourceTable2</ultimateSourceTable>
                    <ultimateSourceTableDesc>col1sourceTable1_desc</ultimateSourceTableDesc>
                </column>
            </finalSourceList>
            <physicalTableName>
                <tableName>table2</tableName>
                <tableDescription>table2_desc</tableDescription>
            </physicalTableName>
            <columnList>
                <column>
                <name>table2_col1</name>
                <columnDesc>table2_col1_desc</columnDesc>
                <columnDataType>String</columnDataType>
                <column/>
            </columnList>
            <finalSourceList>
                <column>
                    <columnName>table2_col1</columnName>
                    <ultimateSourceTable>sourceTable2</ultimateSourceTable>
                    <ultimateSourceTableDesc>col1sourceTable2_desc</ultimateSourceTableDesc>
                </column>
            </finalSourceList>
        </dataBase>
    </Prod>

XSLT used

<?xml version="1.0" encoding="UTF-8"?>
        <xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:output method="xml" version="1.0" encoding="UTF-8"
                indent="yes" />
            <xsl:template match="/">
                <Prod>
                    <xsl:apply-templates />
                </Prod>
            </xsl:template>
            <xsl:key name="kElsByGroup" match="row" use="tablename" />
            <xsl:key name="TableColByGroup" match="row" use="concat(tablename,'|',columnname)" />
            <xsl:template match="row">
                <xsl:apply-templates />
            </xsl:template>
            <xsl:template
                match="row[generate-id()=generate-id(key('kElsByGroup',tablename)[1])]">
                <dataBase>
                    <physicalTableName>
                        <tableName>
                            <xsl:value-of select="tablename"></xsl:value-of>
                        </tableName>
                    </physicalTableName>
                    <columnList>
                        <xsl:for-each
                                           select="//row[generate-id()=generate-id(key('TableColByGroup',concat(tablename,'|',columnname))[1])]">
                            <xsl:element name="column">
                                <name>
                                    <xsl:value-of
                                                        select="columnname"></xsl:value-of>
                                </name>
                            </xsl:element>
                        </xsl:for-each>
                    </columnList>
                    <finalSourceList>
                        <xsl:for-each
                                            select="key('kElsByGroup',tablename)">
                            <xsl:element name="column">
                                <columnName>
                                    <xsl:value-of
                                                        select="columnname"></xsl:value-of>
                                </columnName>
                                <sourceTable>
                                    <xsl:value-of
                                                        select="ultimateSourceTable"></xsl:value-of>
                                </sourceTable>
                            </xsl:element>
                        </xsl:for-each>
                    </finalSourceList>
                </dataBase>
            </xsl:template>
            <xsl:template
                match="row[not(generate-id()=generate-id(key('kElsByGroup',tablename)[1]))]" />
        </xsl:stylesheet>

So, I basically want to have only unique value in my columnList tag. I'm trying to subgroup using muenchian grouping but, I still 2 entries of col1 in my columnList tag. Can someone help me out?


回答1:


In attempt to mold the previous answer into a solution for this question I have come up with

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="table" match="row" use="tablename"/>

  <xsl:key name="col" match="row" use="concat(tablename, '|', columnname)"/>

  <xsl:template match="table">
      <Prod>
          <dataBase>
             <xsl:apply-templates select="row[generate-id() = generate-id(key('table', tablename)[1])]" mode="table"/>
          </dataBase>
      </Prod>
  </xsl:template>

  <xsl:template match="row/*" mode="table"/>

  <xsl:template match="row" mode="table">
      <physicalTableName>
          <xsl:apply-templates mode="table"/>
      </physicalTableName>
      <columnList>
          <xsl:apply-templates select="key('table', tablename)[generate-id() = generate-id(key('col', concat(tablename, '|', columnname))[1])]/*"/>
      </columnList>
      <finalSourceList>
          <xsl:apply-templates select="key('table', tablename)"/>
      </finalSourceList>
  </xsl:template>

  <xsl:template match="row/tablename" mode="table">
      <tableName>
          <xsl:value-of select="."/>
      </tableName>
  </xsl:template>

  <xsl:template match="row/tableDesc" mode="table">
      <tableDescription>
          <xsl:value-of select="."/>
      </tableDescription>
  </xsl:template>

  <xsl:template match="row/*"/>

  <xsl:template match="row/columnname">
      <name>
          <xsl:value-of select="."/>
      </name>
  </xsl:template>

  <xsl:template match="row/columnDesc | row/columnDataType">
      <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="row">
      <column>
          <xsl:apply-templates select="*[not(self::tablename)]" mode="source-list"/>
      </column>
  </xsl:template>

  <xsl:template match="row/*" mode="source-list"/>

  <xsl:template match="row/columnname" mode="source-list">
      <columnName>
          <xsl:value-of select="."/>
      </columnName>
  </xsl:template>

  <xsl:template match="row/ultimateSourceTable | row/ultimateSourceTableDesc" mode="source-list">
      <xsl:copy-of select="."/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/naZYrpu/2



来源:https://stackoverflow.com/questions/62155435/subgroup-in-xslt-with-mutiple-keys

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!