2014-06-06 3 views
1

SQL을 사용하여 XML 노드를 검색하여 부모 노드에 ChildNodes와 Grandchildren이 있는지 확인하는 방법이 있습니까? 일부 XML 파일을 테스트하여 알 수없는 자식이 있는지 확인하려고합니다.SQL을 사용하여 알 수없는 XML 손자 찾기

<form> 
    <ItemType>New Regular</ItemType> 
    <FirstBuyDate>02/01/2007</FirstBuyDate> 
    <FirstShipDate>02/05/2007</FirstShipDate> 
    <ItemBrand>Gillette Blade/Razors</ItemBrand> 
    <ItemDescription>...</ItemDescription> 
    <Size>8.00</Size> 
    <InnerOffInvoice /> 
    <MasterOffInvoice /> 
    <PalletItems> 
    <ID>908402</ID> 
    <PalletShipDate>04/03/13</PalletShipDate> 
    </PalletItems> 
    <ReviewComments /> 
</form> 

이 예제에서는 PalletItems에 자식이 있다는 것을 알고 있습니다. 그래서 나는 테이블을 만들고 그에 따라 데이터를 삽입 할 수 있습니다. 그러나 나는 손자를 모두 <form>으로 받았다는 것을 어떻게 확신 할 수 있습니까? <ItemDescription>과 같이 알려지지 않은 어린이가있는 경우 어떻게해야합니까? 내가 모르는 어린이를 찾으려면 어떻게해야합니까? <form>에 손자가 있는지 어떻게 확인할 수 있습니까?

SELECT distinct Parent.Items.value('local-name(.)', 'varchar(100)') as 'Item' 
    FROM dbo.FormResults 
    CROSS APPLY xmlformfields.nodes('/form/*') as Parent(Items) 

당신이 제안이 중 하나가 손자를 찾기 위해 수행

이 코드는 여기에 있었다 얼마나 많은 아이들이 저를 보여? 감사합니다.

또한 쪽지로 -이 SELECT 문을 사용하여 자식을 XML에 나타나는 순서대로 배치하는 방법을 아는 사람이 있습니까? 코드가 아이들을 잡고 현재 때 임의의 순서로 열에을 표시합니다

Items 
1. FirstBuyDate 
2. Size 
3. ItemType 
4. PalletItems... etc. 

내가 그들을 싶습니다는 다음과 같이 표시 될 :

Items: 
1. ItemType 
2. FirstBuyDate 
3. FirstShipDate 
4. ItemBrand... etc. 

------- -------------- 업데이트 ----------------------

이제는 (/ form // *) 아이들과 손자에게 valex

감사합니다.

어떻게 한 열에 어린이를두고 다음 손자에게 손자를 넣을 수 있습니까?

SELECT distinct Parent.Items.value('local-name(.)', 'varchar(100)') as 'Child of Form', 
CASE when child.items.value('local-name(.)', 'varchar(100)') IS NULL then NULL ELSE 'Has Child' end as 'Grandchild of Form' 
FROM dbo.FormResults 
CROSS APPLY xmlformfields.nodes('/form/*') as Parent(Items) 
Cross Apply parent.items.nodes('/form//*') as child(items) 

답변

2

은 첫 번째 수준의 사용 /form//*에서 또한 부모 노드를 얻을 수 // 대신

SELECT distinct Parent.Items.value('local-name(.)', 'varchar(100)') as 'Item' 
    FROM dbo.FormResults 
    CROSS APPLY xmlformfields.nodes('/form//*') as Parent(Items) 

SQLFiddle example

/form/*의와뿐만 아니라 모든 노드를 얻으려면 :이 같은 것 local-name() 호출에 ../. 구문을 사용하십시오. 는 주문 XQuery expression

for $i in . return count(../*[. << $i]) 

그래서 최종 쿼리를 사용할 수 있습니다 그것은하여 부모 노드와 질서 내에서 아이의 인덱스를 얻으려면 :

SELECT distinct 
      Parent.Items.value('local-name(.)', 'varchar(100)') as 'Item', 
      Parent.Items.value('local-name(../.)', 'varchar(100)') as 'ParentItem', 
      Parent.Items.value('for $i in . return count(../*[. << $i])','int') 
       as ChildIndex 
    FROM dbo.FormResults 
    CROSS APPLY xmlformfields.nodes('/form//*') as Parent(Items) 
    ORDER BY ParentItem,ChildIndex 

SQLFiddle example

+0

끝내 그! 그것은 작동합니다! 정말 고맙습니다! 내가 어떻게 어린이들을 한 칼럼에, 손자들을 다른 칼럼에 넣을 수 있는지 아십니까? (내 제출물에 내 추가 된 코드를 참조하십시오) 정말 고마워! – user3281388

+0

@ user3281388 답변에서 두 번째 쿼리를 확인하십시오. – valex

+0

도움을 주셔서 대단히 감사드립니다! 정말 감사! :) 이것은 잘 작동합니다. ('local-name')을 통해 XML에있는 순서대로 요소를 선택하는 방법을 알고 계십니까? 첫 번째 xml 하위 항목 유형이 ItemType이므로 처음에는 내 행에 넣고 싶습니다. 하지만 내 행은 xml에있는 순서가 아니라 무작위입니다. 어떤 조언 있니? – user3281388

관련 문제