如何将一个XSLT模板用于不同的级别元素?

时间:2016-08-12 11:02:36

标签: xml xslt

我有以下XML文档

DECLARE @Search VARCHAR(10)='07E485';

DECLARE @cmd VARCHAR(MAX);
WITH TableNames AS
(
    SELECT t.*
          ,t.TABLE_CATALOG + '.' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME AS FullTblName
          ,QUOTENAME(t.TABLE_CATALOG)+ '.' + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME) AS FullTblNameQuoted
          , 
          STUFF(
          ( 
            SELECT 'OR ' + QUOTENAME(c.COLUMN_NAME) + '=''' + @Search + ''' ' 
            FROM INFORMATION_SCHEMA.COLUMNS AS c
            WHERE c.TABLE_CATALOG=t.TABLE_CATALOG AND c.TABLE_SCHEMA=t.TABLE_SCHEMA AND c.TABLE_NAME=t.TABLE_NAME
              AND DATA_TYPE LIKE '%char%'  --add more types if needed
            FOR XML PATH('')      
          ),1,3,'') AS WhereFilter

    FROM INFORMATION_SCHEMA.TABLES AS t
    WHERE TABLE_TYPE='BASE TABLE'
)
SELECT @cmd = STUFF(
(
    SELECT DISTINCT 'UNION ALL SELECT (SELECT ' + (SELECT STUFF((SELECT ',' + QUOTENAME(COLUMN_NAME) 
                                                                 FROM INFORMATION_SCHEMA.COLUMNS AS c 
                                                                 WHERE c.TABLE_CATALOG=TableNames.TABLE_CATALOG 
                                                                   AND c.TABLE_NAME =TableNames.TABLE_NAME 
                                                                   AND c.DATA_TYPE LIKE '%char%' 
                                                                 FOR XML PATH('')),1,1,'')) + ' FROM ' + FullTblNameQuoted 
                    + ' WHERE ' + WhereFilter
                    + ' FOR XML PATH(''row''),ROOT(''' +  REPLACE(REPLACE(FullTblName,'.','_'),' ','') + '''),TYPE) AS XmlData '
    FROM TableNames
    WHERE WhereFilter IS NOT NULL
    FOR XML PATH('')
),1,10,'')

SET @cmd='SELECT XmlData FROM(' +  @cmd + ') AS tbl WHERE XmlData IS NOT NULL;'
PRINT LEN(@cmd)
EXEC(@cmd)

我想要这样的东西

<ren:RewardAct>
    <ren:RewardAttrList>
        <ren:RrewardAttr>
            <ren:AttrName>11111111111111</ren:AttrName>
            <ren:AttrValue>11111111111111</ren:AttrValue>
        </ren:RrewardAttr>
    </ren:RewardAttrList>
    <ren:RewardList>
        <ren:Reward>
            <ren:Credit>
                <ren:Division>11111111111111</ren:Division>
                <ren:Region>11111111111111</ren:Region>
            </ren:Credit>
            <ren:RewardAttrList>
                <ren:RewardAttr>
                    <ren:AttrName>11111111111111</ren:AttrName>
                    <ren:AttrValue>11111111111111</ren:AttrValue>
                </ren:RewardAttr>
            </ren:RewardAttrList>
 . . .

对于元素 <RewDocSum> <RewDocSum_ITEM> <Value>1000.00</Value> <Name>string</Name> </RewDocSum_ITEM> </RewDocSum> <RewCategorOutlets> <RewCategorOutlets_ITEM> <GroupSum> <GroupSum_ITEM> <Value>1000.00</Value> <Name>string</Name> </GroupSum_ITEM> </GroupSum> . . . 及其子元素,我尝试使用带参数的模板,因此翻译看起来像

<ren:RewardAttrList>

因此, <xsl:template match="//ren:RewardAct"> <xsl:apply-templates select="ren:RewardAttrList"> <xslt:with-param name="listName" select="'RewDocSum'"/> <xslt:with-param name="itemName" select="'RewDocSum_ITEM'"/> </xsl:apply-templates> <xsl:apply-templates select="ren:RewardList"/> </xsl:template> <xsl:template match="ren:RewardList"> <RewCategorOutlets> <xsl:apply-templates select="ren:Reward"/> </RewCategorOutlets> </xsl:template> <xsl:template match="ren:Reward"> <RewCategorOutlets_ITEM> <xsl:apply-templates select="ren:RewardAttrList"> <xslt:with-param name="listName" select="'GroupSum'"/> <xslt:with-param name="itemName" select="'GroupSum_ITEM'"/> </xsl:apply-templates> <Credits> <xsl:apply-templates select="ren:Credit"/> </Credits> </RewCategorOutlets_ITEM> </xsl:template> <xsl:template match="ren:Credit"> <Credits_ITEM> . . . </Credits_ITEM> </xsl:template> <xsl:template match="//ren:RewardAttrList"> <xsl:param name="listName"/> <xsl:param name="itemName"/> <xsl:element name="{$listName}"> <xsl:apply-templates select="ren:RrewardAttr"> <xslt:with-param name="listItemName" select="$itemName"/> </xsl:apply-templates> </xsl:element> </xsl:template> <xsl:template match="//ren:RrewardAttr"> <xsl:param name="listItemName"/> <xsl:element name="{$listItemName}"> <Value> <xsl:apply-templates select="ren:AttrValue/node()"/> </Value> <Name> <xsl:apply-templates select="ren:AttrName/node()"/> </Name> </xsl:element> </xsl:template> 的模板适用于外部元素,但不适用于内部。

我做错了什么?

感谢您浪费时间和最好的问候。

1 个答案:

答案 0 :(得分:0)

错误在于不同的子元素名称:

ren:RrewardAttr
ren:RewardAttr

在更正元素名称和XSD方案后,带参数的模板工作正常。

谢谢大家,特别是@Tim C