【问题标题】:sub-group using XSLT使用 XSLT 的子组
【发布时间】:2020-05-30 16:15:54
【问题描述】:

我有一个如下所示的源 xml。我正在尝试使用 xslt 转换为所需的格式,如下所示

**Sample XML**

 <table>
    <row>
        <tablename>table1</tablename>
        <columnname>col1</columnname>
        <columnDesc>col1_desc</columnDesc>
        <columnDataType>Number</columnDataType>
        <ultimateSourceTable>sourceTable1</ultimateSourceTable>
    </row>
    <row>
        <tablename>table1</tablename>
        <columnname>col1</columnname>
        <columnDesc>col1_desc</columnDesc>
        <columnDataType>Number</columnDataType>
        <ultimateSourceTable>sourceTable2</ultimateSourceTable>
    </row>
    <row>
        <tablename>table2</tablename>
        <columnname>table2_col1</columnname>
        <columnDesc>table2_col1_desc</columnDesc>
        <columnDataType>String</columnDataType>
        <ultimateSourceTable>sourceTable2</ultimateSourceTable>
    </row>
</table> 

电流输出

   <Prod>
<dataBase>
    <physicalTableName>
        <tableName>table1</tableName>
    </physicalTableName>
    <columnList>
        <name>col1</name>
        <name>col1</name>
        <name>table2_col1</name>
    </columnList>
    <finalSourceList>
        <column>
            <columnName>col1</columnName>
            <ultimateSourceTable>sourceTable1</ultimateSourceTable>
        </column>
        <column>
            <columnName>col1</columnName>
            <ultimateSourceTable>sourceTable2</ultimateSourceTable>
        </column>
    </finalSourceList>
    <physicalTableName>
        <tableName>table2</tableName>
    </physicalTableName>
    <columnList>
        <name>col1</name>
        <name>col1</name>
        <name>table2_col1</name>
    </columnList>
    <finalSourceList>
        <column>
            <columnName>table2_col1</columnName>
            <ultimateSourceTable>sourceTable2</ultimateSourceTable>
        </column>
    </finalSourceList>
</dataBase>

期望的输出:

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

XSLT:

      <?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>

所以,我基本上只想在我的 columnList 标记中具有唯一值。我正在尝试使用 muenchian 分组进行分组,但是我的 columnList 标记中仍然有 2 个 col1 条目。有人可以帮我吗?

【问题讨论】:

  • 您的输入样本只有一个 table 元素,完整样本中还能有更多吗?结果中是否有一个table 映射到一个dataBase?如果输入中已经有一个 table 容器元素,我不理解按表名分组的尝试。看来您可以使用匹配的模板处理 table,创建相应的结果元素容器,我不确定它会是 dataBase 还是其他东西。
  • 是的,一个数据库中可以有多个物理表。
  • 我已经修改了输出文件。我会有多个表,每个表都有列和它的最终源表。这就是我使用表格分组的原因
  • 谢谢你帮助我马丁。我只有一个查询,我必须在 columnList 中包含另外 2 个属性,例如 columnDesc 和 columnDatatype。我无法选择这些值。我尝试将其添加为新模板。我已经编辑了所需的输出。你能帮忙吗
  • 考虑针对该新要求提出一个新的、单独的问题。

标签: html xml xslt xslt-grouping


【解决方案1】:

源中的单个table 元素包含不同表的rows,您似乎可以使用处理rows 两次的模式来解决它,一次创建结果表的数据,第二次创建结果表的数据创建每个结果表的详细信息:

<?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: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">
      <physicalTableName>
          <xsl:value-of select="tablename"/>
      </physicalTableName>
      <columnList>
          <xsl:apply-templates select="key('table', tablename)[generate-id() = generate-id(key('col', concat(tablename, '|', columnname))[1])]/columnname"/>
      </columnList>
      <finalSourceList>
          <xsl:apply-templates select="key('table', tablename)"/>
      </finalSourceList>
  </xsl:template>

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

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

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

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

</xsl:stylesheet>

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

【讨论】:

    猜你喜欢
    • 2016-04-23
    • 2012-09-04
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多