如何使用Table中的属性创建XML节点

时间:2016-02-18 15:34:20

标签: sql-server xml sql-server-2008

我有以下示例表

enter image description here

此处代码

CREATE TABLE XMLData
(
    NodeName NVARCHAR(255),
    AttributA NVARCHAR(255),
    AttributB NVARCHAR(255),
    AttributC NVARCHAR(255),
) 

INSERT INTO XMLData VALUES 
('RowA','','abcd','efgh'),
('RowB','wxyz',NULL,NULL),
('RowC',NULL,'qwer','tyui'),
('RowD','stuv','erty','fghj')

SELECT * FROM dbo.XMLData

如何获取以下XML?

<NodeA>
  <NodeB />
  <NodeC AttributeX="">
    <RowA AttributeA="" AttributeB="abcd" AttributeC="efgh" />
    <RowB AttributeA="wxyz" />
    <RowC AttributeB="qwer" AttributeC="tyui" />
    <RowD AttributeA="stuv" AttributeB="erty" AttributeC="fghj" />
  </NodeC>
</NodeA>

我是XML的初学者,但我尝试使用类似的东西

SELECT
    (
    SELECT
        (
        SELECT '' AS '@AttributeX' FOR XML PATH('NodeC'),TYPE
        -- How to get table rows here ?
        )
    FOR XML PATH('NodeB'),TYPE -- Here it creates additional end NodeB tag
    )
FOR XML PATH('NodeA'),TYPE

1 个答案:

答案 0 :(得分:1)

这几乎是你想要的。正如我在评论中所说,您将无法动态创建元素的名称(<RowA>等)。为此你必须使用动态SQL,我认为这不是你想要的......

这是我的建议:

SELECT '' AS [NodeB]
      ,'' AS [NodeC/@AttributeX]
      ,(
          SELECT x.NodeName AS [@NodeName]
                ,x.AttributA AS [@AttributeA]
                ,x.AttributB AS [@AttributeB]
                ,x.AttributC AS [@AttributeC]
          FROM XMLData AS x
          FOR XML PATH('Row'),TYPE
       ) AS NodeC
FOR XML PATH(''),ROOT('NodeA')

结果

<NodeA>
  <NodeB></NodeB>
  <NodeC AttributeX="">
    <Row NodeName="RowA" AttributeA="" AttributeB="abcd" AttributeC="efgh" />
    <Row NodeName="RowB" AttributeA="wxyz" />
    <Row NodeName="RowC" AttributeB="qwer" AttributeC="tyui" />
    <Row NodeName="RowD" AttributeA="stuv" AttributeB="erty" AttributeC="fghj" />
  </NodeC>
</NodeA>

这是一个获得&#34;动态&#34;的XSLT。上面的XML中的元素名称

Credits to Tim C

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[@NodeName]">
        <xsl:element name="{@NodeName}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="@NodeName" />
</xsl:stylesheet>

结果是Test it here

<NodeA>
  <NodeB/>
  <NodeC AttributeX="">
    <RowA AttributeA="" AttributeB="abcd" AttributeC="efgh"/>
    <RowB AttributeA="wxyz"/>
    <RowC AttributeB="qwer" AttributeC="tyui"/>
    <RowD AttributeA="stuv" AttributeB="erty" AttributeC="fghj"/>
  </NodeC>
</NodeA>