从父节点xml sql服务器检索所有子节点

时间:2018-10-10 10:17:51

标签: sql sql-server xml

我有这个xml:

<viewNode xsi:type="View:Projection" name="Projection_1">
<endUserTexts label=" "/>
<element name="CITY">
  <inlineType primitiveType="CHAR" length="0" precision="0" scale="0"/>
</element>
<element name="ROAD_ID">
  <inlineType primitiveType="CHAR" length="0" precision="0" scale="0"/>
</element>
<element name="LEN">
  <inlineType primitiveType="CHAR" length="0" precision="0" scale="0"/>
</element>
<element name="CITY2">
  <inlineType primitiveType="CHAR" length="0" precision="0" scale="0"/>
</element>
<element name="F">
  <inlineType name="INTEGER" primitiveType="INTEGER" length="0" precision="0" scale="0"/>
</element>
<elementFilter elementName="F">
  <valueFilter xsi:type="Column:SingleValueFilter" including="true" value="1"/>
</elementFilter>
<input>
  <viewNode xsi:type="View:JoinNode">#/0/Join_1</viewNode>
  <mapping xsi:type="Type:ElementMapping" targetName="CITY" sourceName="CITY"/>
  <mapping xsi:type="Type:ElementMapping" targetName="ROAD_ID" sourceName="ROAD_ID"/>
  <mapping xsi:type="Type:ElementMapping" targetName="LEN" sourceName="LEN"/>
  <mapping xsi:type="Type:ElementMapping" targetName="CITY2" sourceName="CITY2"/>
  <mapping xsi:type="Type:ElementMapping" targetName="F" sourceName="F"/>
</input></viewNode>

这是我检索数据的代码:

SELECT 
Tab.Col.value('../@name','nvarchar(50)') as ViewNode,
Tab.Col.value('@name','nvarchar(50)') as Name,
Tab.Col.value('(endUserTexts/@label)[1]','nvarchar(50)') as Label,  
Tab.Col.value('(inlineType/@primitiveType)[1]','nvarchar(50)') as PrimitveType, 
Tab.Col.value('(inlineType/@length)[1]','nvarchar(50)') as Length,  
Tab.Col.value('(inlineType/@precision)[1]','nvarchar(50)') as Precision,    
Tab.Col.value('(inlineType/@scale)[1]','nvarchar(50)') as Scale 
FROM @x.nodes('/viewNode/element') AS Tab(Col)

这种方法可以工作并检索每个元素的数据,但是我也想从elementFilter检索数据,并将其视为另一个元素。我的问题是,有一种方法可以检索父节点viewNode的所有子节点吗?

类似FROM @x.nodes('/viewNode/ANYCHILDNODE') AS Tab(Col)

1 个答案:

答案 0 :(得分:1)

首先:提供的示例不能完整,因为缺少名称空间xsi的声明。在我的示例中,我添加了一个伪声明...

  

这种方式可以工作并检索每个元素的数据,但是我会   还希望从elementFilter中检索数据,并将其视为   如果这是另一个要素。我的问题是,有一种方法可以找回   父节点viewNode的所有子节点?就像是   FROM @x.nodes('/viewNode/ANYCHILDNODE') AS Tab(Col)

在这种情况下,最好提供预期的输出...

<element><elementFilter>不共享相同的属性。 <input>完全是另外一回事,包括与1:n相关的<mapping>数组本身...

所以:是的,有*的意思是ANYCHILD。像XPath这样的/viewNode/*将返回<viewNode>以下的所有子级。然后,您可以使用local-name()对元素的名称进行通用反应。在以下Clode中,我向substring中添加了XPath 谓词,以便返回以短语element开头的元素。这将返回<element><elementFilter>,但将忽略<input>。试试看:

DECLARE @x XML=
N'<viewNode xmlns:xsi="dummy" xsi:type="View:Projection" name="Projection_1">
  <endUserTexts label=" " />
  <element name="CITY">
    <inlineType primitiveType="CHAR" length="0" precision="0" scale="0" />
  </element>
  <element name="ROAD_ID">
    <inlineType primitiveType="CHAR" length="0" precision="0" scale="0" />
  </element>
  <element name="LEN">
    <inlineType primitiveType="CHAR" length="0" precision="0" scale="0" />
  </element>
  <element name="CITY2">
    <inlineType primitiveType="CHAR" length="0" precision="0" scale="0" />
  </element>
  <element name="F">
    <inlineType name="INTEGER" primitiveType="INTEGER" length="0" precision="0" scale="0" />
  </element>
  <elementFilter elementName="F">
    <valueFilter xsi:type="Column:SingleValueFilter" including="true" value="1" />
  </elementFilter>
  <input>
    <viewNode xsi:type="View:JoinNode">#/0/Join_1</viewNode>
    <mapping xsi:type="Type:ElementMapping" targetName="CITY" sourceName="CITY" />
    <mapping xsi:type="Type:ElementMapping" targetName="ROAD_ID" sourceName="ROAD_ID" />
    <mapping xsi:type="Type:ElementMapping" targetName="LEN" sourceName="LEN" />
    <mapping xsi:type="Type:ElementMapping" targetName="CITY2" sourceName="CITY2" />
    <mapping xsi:type="Type:ElementMapping" targetName="F" sourceName="F" />
  </input>
</viewNode>';

-注意名称空间...

WITH XMLNAMESPACES('dummy' AS xsi)
SELECT 
Tab.Col.value('../@name','nvarchar(50)') as ViewNode,
Tab.Col.value('@name','nvarchar(50)') as Name,
Tab.Col.value('(endUserTexts/@label)[1]','nvarchar(50)') as Label,  
Tab.Col.value('(inlineType/@primitiveType)[1]','nvarchar(50)') as PrimitveType, 
Tab.Col.value('(inlineType/@length)[1]','nvarchar(50)') as Length,  
Tab.Col.value('(inlineType/@precision)[1]','nvarchar(50)') as Precision,    
Tab.Col.value('(inlineType/@scale)[1]','nvarchar(50)') as Scale,
Tab.Col.value('@elementName','nvarchar(50)') as filter_elementName,
Tab.Col.value('(valueFilter/@xsi:type)[1]','nvarchar(50)') as filter_ValueFilterType,
Tab.Col.value('(valueFilter/@including)[1]','bit') as filter_Including,
Tab.Col.value('(valueFilter/@value)[1]','nvarchar(50)') as filter_value
FROM @x.nodes('/viewNode/*[substring(local-name(),1,7)="element"]') AS Tab(Col)