2014-10-08 72 views
0

編輯:爲見This link後續問題修改XML訂購中級複雜類型元素的名稱

我在SQL Server 2008 R2中,創建一個XML文件大​​查詢,但它失敗以針對我的XSD模式進行驗證,因爲某些中級元素的顯示順序錯誤。下面是一個例子XML文件來說明我的意思:

<Things> 
    <Thing> 
    <Racecars> 
     <Racecar> 
     <Colour>Red</Colour> 
     <Rockets>Y</Rockets> 
     </Racecar> 
     <Racecar> 
     <Colour>Blue</Colour> 
     <Rockets>N</Rockets> 
     </Racecar> 
    </Racecars> 
    </Thing> 
    <Thing> 
    <Numbers> 
     <Number> 
     <NumericName>1</NumericName> 
     <WrittenName>One</WrittenName> 
     </Number> 
     <Number> 
     <NumericName>2</NumericName> 
     <WrittenName>Two</WrittenName> 
     </Number> 
    </Numbers> 
    </Thing> 
    <Thing> 
    <Letters> 
     <Letter> 
     <AlphaName>A</AlphaName> 
     <PhoneticName>Ay</PhoneticName> 
     </Letter> 
     <Letter> 
     <AlphaName>B</AlphaName> 
     <PhoneticName>Bee</PhoneticName> 
     </Letter> 
    </Letters> 
    </Thing> 
</Things> 

的XML明確的命令作品意味着包含一些屬性每組都是爲了(在這種情況下,底層),但我不知道的方式知道如何控制直接在(在這種情況下)「Thing」級別下面的屬性的順序。如何指定「Thing」的子元素應按名稱的字母順序出現,當SQL沒有屬性數據給ORDER BY時?

正如我所提到的,這是一個很大的XML,它有很多不同的元素,它們並不總是全部出現,所以如果有某種方法可以將某個級別的所有子元素排序而不影響排序沒有必要硬編碼每個元素名稱的孫子元素,這將是非常好的。

我已經搜遍遍地都無濟於事。我已經在我的XML輸出中查看了事後xquery修改(在我看來,這是最實用的解決方案,因爲某些要排序的元素具有minOccurs = 0),或者作爲FOR XML EXPLICIT命令設計的一部分(這種方式似乎是最有效的,因爲這樣可以防止而不是解除錯誤),但是據我所知,沒有任何東西可以工作。

我當然可以從模式文件中刪除約束條件,但如果可能的話儘量避免這種情況,因爲給予不精確性似乎是錯誤的方向。

通過上述文件,這是結果,我會考慮的理想:

<Things> 
    <Thing> 
    <Letters> 
     <Letter> 
     <AlphaName>A</AlphaName> 
     <PhoneticName>Ay</PhoneticName> 
     </Letter> 
     <Letter> 
     <AlphaName>B</AlphaName> 
     <PhoneticName>Bee</PhoneticName> 
     </Letter> 
    </Letters> 
    </Thing> 
    <Thing> 
    <Numbers> 
     <Number> 
     <NumericName>1</NumericName> 
     <WrittenName>One</WrittenName> 
     </Number> 
     <Number> 
     <NumericName>2</NumericName> 
     <WrittenName>Two</WrittenName> 
     </Number> 
    </Numbers> 
    </Thing> 
    <Thing> 
    <Racecars> 
     <Racecar> 
     <Colour>Red</Colour> 
     <Rockets>Y</Rockets> 
     </Racecar> 
     <Racecar> 
     <Colour>Blue</Colour> 
     <Rockets>N</Rockets> 
     </Racecar> 
    </Racecars> 
    </Thing> 
</Things> 

正如你所看到的,下面的「一事一議」三個要素正在按字母順序排序(字母,數字,賽車),但所有其中每個元素的順序不變。

請讓我知道你是否希望我寫出一個SELECT ... FOR XML EXPLICIT來生成上面的示例XML;我會很樂意這樣做 - 我只是希望答案直接在上面的XML中以xquery的形式出現,所以認爲不太可能需要!

+0

您可以使用XML路徑,也給樣本數據與當前查詢嘗試相處? – radar 2014-10-08 15:47:39

+0

不太明白你的問題是什麼。 2之間唯一不同的是,第一個XML在''標籤外部有''。其餘的是一樣的:字母,數字,Racecars。 – 2014-10-08 15:56:55

+0

該死的!當編輯縮進以使其在帖子中看起來不錯時,我必須無意中發佈了兩次相同的xml ......忍耐着我。對 - 我編輯了這篇文章。道歉。 – 2014-10-08 16:25:47

回答

0

您必須重建<Things/>元素,按<Thing/>的名稱排序。這段代碼按第一個孩子的名字排序,因爲我們需要一個值來排序。關於給定的輸入,似乎沒有必要在內部訂購<Thing/>(甚至可能是錯誤的)。

element Things { 
    for $thing in /Things/Thing 
    let $name := local-name(($thing/*)[1]) 
    order by $name 
    return $thing 
} 
+0

請原諒我,我對這段代碼的背景有點困惑 - 請問您能提供一些關於如何應用重建的更多信息嗎?我認爲這對我來說是一個陡峭的學習曲線!我應該使用你的答案作爲xquery的一部分嗎?如果是的話,它適合於哪種語法?它看起來像別的東西,但目前谷歌沒有太多的幫助... – 2014-10-09 08:28:08

+0

這是完整的XQuery代碼應用上述轉換。 'element Things {...}'也可以寫成' {...}'並構造XML節點。在內部,代碼段遍歷所有''並對其重新排序。在SQL查詢中何處以及如何運行代碼取決於您如何存儲數據;如果您可以在XML上運行任何XQuery,請將其替換。 – 2014-10-09 08:48:17

+0

我會問一個新問題;我認爲我的例子不是很好,當我嘗試建議的方法時,我遇到了錯誤。當我改變語法來匹配我的(知名危險的)小知識時,我得到了一些在這個例子中有用的東西,但不是真正的數據。我會用更好的書面形式回答這個問題。 – 2014-10-09 13:02:44