2017-05-20 2 views
1

Ich brauche Attributnamen in alphabetischer Reihenfolge zu bestellen, und ich habe folgenden Code erstellt, aber es hat xml wie es ist:Sortieren Attributnamen in XML mit T-SQL

DECLARE @xml XML = N'<tt> 
     <cpost s="a" cena="0.0000" cpost_id="16385" flprt="1" moq="0" 
    valuta_id="2" nmatr_id="14117" norg_id="1791" /> 

     </tt>' 

    SELECT 
     t.query('.') 
    FROM @xml.nodes('*/*') AS t(t) 
    ORDER BY t.value('local-name(.)','nvarchar(max)') 
    FOR XML PATH(''), TYPE, ROOT('tt') 

Wo habe ich Fehler machen?

+0

Ich denke nicht, dass es möglich ist, die Sortierung auf Attribut zu erhalten basiert. Versuchen Sie, diese https://msdn.microsoft.com/en-us/library/ms187107(v=sql.90).aspx –

+0

Blick auf [diesen Link] (https://stackoverflow.com/q/7230739/ 5089204). Die Sortierreihenfolge der Elemente bleibt erhalten, nicht jedoch die Reihenfolge der Attribute. Es gibt etwas, das "Canonical XML" genannt wird, aber die Frage ist: Warum brauchen Sie das? Es gibt AFAIC keine * hübsche * oder * elegante * Möglichkeit, dies zu erreichen ... – Shnugo

Antwort

3

Nicht schön, aber das ist, wo mein Denken mich nimmt.

dbFiddle

Beispiel

DECLARE @xml XML = N' 
<tt> 
    <cpost s="a" cena="0.0000" cpost_id="16385" flprt="1" moq="0" valuta_id="2" nmatr_id="14117" norg_id="1791" /> 
</tt>' 


Declare @S varchar(max) = '' 

Select @S = @S + concat(Item,'="',Value,'" ') 
From (
     Select Top 1000 
       Item = attr.value('local-name(.)','varchar(100)') 
       ,Value = attr.value('.','varchar(max)') 
     From @XML.nodes('/tt/cpost') as A(r) 
     Cross Apply A.r.nodes('./@*') AS B(attr) 
     Order By attr.value('local-name(.)','varchar(100)') 
    ) A 

Select convert(xml,'<tt><cpost '[email protected]+'/></tt>') 

Returns

<tt> 
    <cpost cena="0.0000" cpost_id="16385" flprt="1" moq="0" nmatr_id="14117" norg_id="1791" s="a" valuta_id="2" /> 
</tt> 

EDIT - Added a n In-Line-Ansatz

DECLARE @xml XML = N' 
<tt> 
    <cpost s="a" cena="0.0000" cpost_id="16385" flprt="1" moq="0" valuta_id="2" nmatr_id="14117" norg_id="1791" /> 
</tt>' 

Select convert(xml,'<tt><cpost '+Stuff((Select ' ' +concat(Item,'="',Value,'" ') 
From (
     Select Top 1000 
       Item = attr.value('local-name(.)','varchar(100)') 
       ,Value = attr.value('.','varchar(max)') 
     From @XML.nodes('/tt/cpost') as A(r) 
     Cross Apply A.r.nodes('./@*') AS B(attr) 
     Order By attr.value('local-name(.)','varchar(100)') 
    ) A 
For XML Path ('')),1,1,'') +'/></tt>') 
+0

nicht genau, Ergebnis muss die XML-Datei aber so sein: " '" –

+0

Ja! Vielen Dank! –

+0

@SashaFes Glücklich es half. Ich bin mir sicher, dass es einen klügeren Weg geben muss, aber es entgeht mir an diesem Punkt. –