2011-02-02 115 views
0

我想查詢有關XML的元數據,以幫助確定某些XML的結構。我有一個49 MB的XML文件,我只需要知道所有屬性和子標籤的列表以及關於它們的一些基本信息。我可以從XML本身查詢它,還是必須費力地查閱它並查找其中可能存在的每個元素和屬性?沒有可用的模式定義。查詢xml的結構,而不是SQL Server 2005中的數據

鑑於一些隨機的XML如下所示:

DECLARE @x xml 
SET @x = 
'<People> 
<Person age="35"> 
    <Name>Pete</Name> 
    <Phone> 
    <Mobile>555-555-1234</Mobile> 
    <Home>555-555-0001</Home> 
    </Phone> 
</Person> 
<Person age="40" height="70 inches"> 
    <Name>Paul</Name> 
    <Phone> 
    <Mobile>555-555-4567</Mobile> 
    </Phone> 
</Person> 
<Person age="24"> 
    <Name>Susan</Name> 
    <Phone> 
    <Home>555-555-2323</Home> 
    </Phone> 
</Person> 
</People>' 

我將如何查詢這回像下面這樣?我不需要一個記錄集(儘管那當然會很好)。爲了得到不同的部分,我不得不反覆查詢。我可能必須先看到首先有一個root People標記,然後查詢People並查看Person標記,然後才能看到該標記下的Name和Phone標記,依此類推。

People maxcount=1 
People.Person maxcount=3 [age maxlen=2 maxcount=3] [weight maxlen=9 maxcount=1] 
Person.Name textnode maxcount=1 maxlen=5 
Person.Name.Phone maxcount=1 
Person.Name.Mobile textnode maxcount=1 maxlen=12 
Person.Name.Home textnode maxcount=1 maxlen=12 
+0

你爲什麼要使用SQL Server來做到這一點? – 2011-02-03 00:41:29

回答

0

這種類型的分析可能是通過結構化程序代碼最好的。僅僅因爲xml可能在數據庫中並不意味着xml的分析必須在那裏完成。

2

提取結構是可行的(如下面的查詢所示),但像John說的那樣...爲什麼?如果它強制執行約束,則使用xsd,然後將其讀入到您的應用程序中。

declare @data xml 

set @data = ' 
<People> 
<Person age="35"> 
    <Name>Pete</Name> 
    <Phone> 
    <Mobile>555-555-1234</Mobile> 
    <Home>555-555-0001</Home> 
    </Phone> 
</Person> 
<Person age="40" height="70 inches"> 
    <Name>Paul</Name> 
    <Phone> 
    <Mobile>555-555-4567</Mobile> 
    </Phone> 
</Person> 
<Person age="24"> 
    <Name>Susan</Name> 
    <Phone> 
    <Home>555-555-2323</Home> 
    </Phone> 
</Person> 
</People>' 

;with c_Tree (Parent, Node) 
as ( select p.n.value('local-name(..)[1]', 'varchar(max)'), 
       p.n.value('local-name(.)[1]', 'varchar(max)') 
     from @data.nodes('//*[local-name(.) > ""]') p(n) 
    ), 
    c_Expand(lvl, RootName, NodeName) 
as ( select 0, 
       Parent, 
       Node 
     from c_Tree 
     where Parent = '' 
     union all 
     select ce.lvl + 1, 
       ct.Parent, 
       ct.Node 
     from c_Tree ct 
     join c_Expand ce on 
       ce.NodeName = ct.Parent 
) 
select RootName+'>'+NodeName, 
     lvl 
from  c_Expand 
order 
by  lvl asc;