问题
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