2012-10-27 13 views
7
declare @xmlsample xml = 
'<root> 
    <solution> 
     <solutionnumber>1</solutionnumber> 
      <productgroup> 
       <productcategory> 
        <price>100</price> 
        <title>Some product</title> 
        <tax>1</tax> 
       </productcategory> 
      </productgroup> 
      <productcategory2> 
        <price>200</price> 
        <title>Some other product</title> 
        <tax>2</tax> 
      </productcategory2> 
    </solution> 
    <solution> 
     <solutionnumber>2</solutionnumber> 
      <productcategory2> 
        <price>200</price> 
        <title>Some other product</title> 
        <tax>2</tax> 
      </productcategory2> 
    </solution> 
</root>' 

SELECT 
    --T.C.value('(./ancestor::ns1:solutionNumber)[1]', 'varchar(50)') AS solutionnumber ?? no clue 
    T.C.value('(price)[1]', 'numeric(18,2)') AS price 
    ,T.C.value('(title)[1]', 'varchar(50)') AS title 
    ,T.C.value('(tax)[1]', 'numeric(18,2)') AS tax 
FROM @xmlsample.nodes('//node()[title]') AS T(C) 

एक्सएमएल का एक प्रतिनिधित्व मैं SQL सर्वर 2008 आर 2 में फेंकने का प्रयास कर रहा हूं। मुझे "शीर्षक" नोड मिल गया है और मुझे आवश्यक मूल्यों को पकड़ना है जो उत्पाद श्रेणी में हैं। अब मैं "समाधान संख्या" प्राप्त करना चाहता हूं हालांकि यह उत्पाद के ऊपर एक या अधिक माता-पिता नोड्स हो सकता है क्योंकि कुछ उत्पाद "समूह" हैं।एसक्यूएल सर्वर .nodes() नाम से एक्सएमएल पैरेंट नोड्स

मैं इसे प्राप्त करने तक नाम ("solutionnumber") द्वारा पैरेंट नोड्स की जांच कैसे करूं? किसी भी सहायता के लिए धन्यवाद।

+0

गलत शब्दावली। फिर भी, "समाधान संख्या" की तलाश में है। – duffn

उत्तर

2

शायद मैं इस पीछे के बारे में जा रहा था। एकाधिक क्रॉस लागू होता है नौकरी। किसी अन्य मंच पर कुछ सहायता के लिए धन्यवाद।

SELECT 
    --T.C.value('(./ancestor::ns1:solutionNumber)[1]', 'varchar(50)') AS solutionnumber ?? no clue 
    m.c.value('(solutionnumber)[1]', 'int') as solutionnumber 
    ,T.C.value('(price)[1]', 'numeric(18,2)') AS price 
    ,T.C.value('(title)[1]', 'varchar(50)') AS title 
    ,T.C.value('(tax)[1]', 'numeric(18,2)') AS tax 
FROM @xmlsample.nodes ('//solution') as m (c) 
cross apply m.c.nodes ('.//node()[title]') as t(C) 
2

मेरे ज्ञान का कोई सीधा तरीका नहीं है।

SELECT 
    COALESCE(T.C.value('../solutionnumber[1]', 'INT'), 
      T.C.value('../../solutionnumber[1]', 'INT'), 
      T.C.value('../../../solutionnumber[1]', 'INT')) solutionnumber, 
    T.C.value('(price)[1]', 'numeric(18,2)') AS price, 
    T.C.value('(title)[1]', 'varchar(50)') AS title, 
    T.C.value('(tax)[1]', 'numeric(18,2)') AS tax 
    FROM 
    @xmlsample.nodes('//node()[title]') AS T (C) 

ध्यान दें कि <solutionnumber> वास्तव में पूर्वजों में से एक के एक भाई और नहीं एक पूर्वज ही है: हालांकि, अगर आप अपने तरीके से खोज करने के लिए COALESCE उपयोग कर सकते हैं।

इस समाधान के लिए आपको समय से पहले अधिकतम गहराई जानने की आवश्यकता है।


तुम भी, इस समाधान का उपयोग करता है, तो आप इसके बजाय पीछे की ओर से आगे जाने के कर सकते हैं:

SELECT solutionNodes.solutionNode.value('solutionnumber[1]','INT') AS solutionnumber, 
    T.C.value('(price)[1]', 'numeric(18,2)') AS price, 
    T.C.value('(title)[1]', 'varchar(50)') AS title, 
    T.C.value('(tax)[1]', 'numeric(18,2)') AS tax 
FROM @xmlsample.nodes('//solution') AS solutionNodes (solutionNode) 
CROSS APPLY (SELECT solutionNodes.solutionNode.query('.')) solutions(solutionXML) 
CROSS APPLY solutions.solutionXML.nodes('//node()[title]') T (C) 

यह तथ्य यह है कि <solutionnumber> टैग एक <solution> टैग का एक सीधा बच्चा है उपयोग करता है। पहले सभी <solution> टैग पाए जाते हैं। इसके सभी शीर्षक वंशजों की तुलना में एक क्रॉस लागू होता है। चूंकि आप नोड पर नोड्स फ़ंक्शन का उपयोग नहीं कर सकते हैं, इसलिए "क्वेरी ('।')" की गणना बीच में होती है।

उपरोक्त समाधान के अलावा, यह <solution> टैग 0d> टैग abd के बीच किसी भी दूरी को संभाल सकता है।

1

एसक्यूएल सर्वर पूर्वजों को पीछे की तरफ जाने का समर्थन नहीं करता है, इसलिए एक्सएमएल में उतरते समय caching को पूर्वजों के पॉइंटर का एक चौराहे तरीका है।

declare @xmlsample xml = 
'<root> 
    <solution> 
     <solutionnumber>1</solutionnumber> 
      <productgroup> 
       <productcategory> 
        <price>100</price> 
        <title>Some product</title> 
        <tax>1</tax> 
       </productcategory> 
      </productgroup> 
      <productcategory2> 
        <price>200</price> 
        <title>Some other product</title> 
        <tax>2</tax> 
      </productcategory2> 
    </solution> 
    <solution> 
     <solutionnumber>2</solutionnumber> 
      <productcategory2> 
        <price>200</price> 
        <title>Some other product</title> 
        <tax>2</tax> 
      </productcategory2> 
    </solution> 
</root>'; 

WITH Xml_CTE AS 
(
    SELECT node.query('*') AS children, 
      node.value('fn:local-name(.)','varchar(100)') localName, 
      node.exist('title') IsTitleParent, 
      CAST(null as xml) as solution 
     FROM @xmlsample.nodes('/*') AS root(node) 
    UNION ALL 
    SELECT node.query('*') AS children, 
      node.value('fn:local-name(.)','varchar(100)') localName, 
      node.exist('title') IsTitleParent, 
      CASE WHEN node.value('fn:local-name(.)', 'varchar(100)') = 'solution' 
       THEN node.query('.') 
       ELSE solution END 
     FROM Xml_CTE x 
CROSS APPLY x.children.nodes('*') AS child(node) 
) 
SELECT solution.value('(solution/solutionnumber/text())[1]', 'int') solutionNumber 
     ,children.value('(price)[1]', 'numeric(18,2)') price 
     ,children.value('(title)[1]', 'varchar(50)') title 
     ,children.value('(tax)[1]', 'numeric(18,2)') tax 
    FROM Xml_CTE 
WHERE IsTitleParent = 1 -- matches .nodes('//node()[title]') 
OPTION (MAXRECURSION 0); 
0

यह मेरी ओर से पूरी तरह से काम करेगा ...

Declare @SomeXML XML 
SET @SomeXML = '<SomeValue>GGGG</SomeValue><SomeValue>MMMM</SomeValue><SomeValue>AAA</SomeValue>' 

select ROW_NUMBER() over (order by b), b.value('.', 'varchar(50)') 
from @SomeXML.nodes('(/SomeValue)') AS a(b) 
संबंधित मुद्दे