2017-03-09 113 views
2

我們的表像SQL查詢動態節點

StudentNo Name Subject Mark Grade 
1   John English 41  A 
1   John Hindi 42  B 

我們希望從這個表中的XML格式如下。

<Student> 
    <Name>John</Name> 
    <Subject> 
    <English> 
      <Mark>41</Mark> 
      <Grade>A</Grade> 
    </English> 
    <Hindi> 
      <Mark>42</Mark> 
      <Grade>B</Grade> 
    </Hindi> 
</Subject> 
<Student> 

這裏主題名稱節點應該動態生成。

在此先感謝您的答案。

回答

2

這與SQL Data as XML Element非常相似 - 以至於我認爲它可能是重複的 - 但我想爲您的上下文解釋一下爲什麼這不是最好的主意。在我回答這個問題時,我展示了一種非常冒險的方式,你可以做到這一點,但這不是最好的主意。

您的XML幾乎不可能爲其創建模式。該XML的任何消費者將永遠無法確定哪些值可能會作爲元素出現。而不是嘗試創建動態元素,你應該使用某種屬性。你甚至可以用xsi:type在你的XML中創建一個抽象類型(儘管在我的例子中,我只是使用了一個普通的舊屬性 - 你可以選擇任何對你的用戶最有意義的屬性)。對於XML的查詢將是:

declare @subjects TABLE(studentno int, name varchar(10), subjecT varchar(10), mark int, grade char(1)) 

INSERT @subjects 
VALUES 
(1, 'John','English', 41,'A'), 
(1, 'John','Hindi', 42,'B') 

select 
    s.Name 

    ,(SELECT 
     s2.Subject as '@type' 
     ,s2.Mark 
     ,s2.Grade 
    FROM @subjects s2 
    WHERE s2.studentno = s.studentno 
    FOR XML PATH('Subject'), ROOT('Subjects'), TYPE) 
from @subjects s 
GROUP BY s.name, s.studentno 
FOR XML PATH('Student') 

生產:

<Student> 
    <Name>John</Name> 
    <Subjects> 
    <Subject type="English"> 
     <Mark>41</Mark> 
     <Grade>A</Grade> 
    </Subject> 
    <Subject type="Hindi"> 
     <Mark>42</Mark> 
     <Grade>B</Grade> 
    </Subject> 
    </Subjects> 
</Student> 

這個XML將有可能使受到消費者,在那裏他們可以,例如,重複的主題意識不知道什麼科可能在那裏(並且不需要假設Subjects的每個直接子節點實際上都是一個主題,而不是在新模式的新版本中添加的其他類型的節點)。


如果你真的需要該輸出,我寧願使用XSLT轉換上面的格式輸出,如:

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

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

    <xsl:template match="Subject"> 
     <xsl:element name="{@type}"> 
      <xsl:apply-templates /> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="Subjects"> 
     <xsl:element name="Subject"> 
      <xsl:apply-templates /> 
     </xsl:element> 
    </xsl:template> 
</xsl:transform> 

讓你

<?xml version="1.0" encoding="UTF-8"?> 
<Student> 
    <Name>John</Name> 
    <Subject> 
     <English> 
     <Mark>41</Mark> 
     <Grade>A</Grade> 
     </English> 
     <Hindi> 
     <Mark>42</Mark> 
     <Grade>B</Grade> 
     </Hindi> 
    </Subject> 
</Student> 

注意你不能用SQL Server完全做到這一點 - 但你必須求助於構建XML字符串並將其轉換爲XML,就像我的其他答案一樣。

+0

但是,我們究竟需要XML的格式如下 約翰 一個

+0

我會創建一個XSLT樣式表來處理在這種情況下出現的SQL - 看看我的其他答案,它可能與SQL Server但它變得非常難看。您必須手動創建一個XML字符串並將其轉換爲XML - FOR XML結構都不支持您要做的事情。 –

+0

我已經添加了一個可以轉換它的XSLT的例子。 –