【问题标题】:retrieve all child nodes from a parent node xml sql server从父节点xml sql server检索所有子节点
【发布时间】:2018-10-10 10:17:51
【问题描述】:

我有这个 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)

【问题讨论】:

  • 如果子节点是分层顺序的,那么通过使用 CROSS APPLY kodyaz.com/t-sql/… 从上到下开始,您可以获得所有所需的项目级别数据。但是由于它们处于同一级别,您可以简单地使用两个查询并使用 UNION ALL
  • 我认为您还可以添加 w3.org/2001/XMLSchema-instance"> 和 以消除由于 XML 中缺少定义而导致的错误
  • 确实有,我只是复制了部分xml以简化问题

标签: sql sql-server xml


【解决方案1】:

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

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

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

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

所以:是的,* 的意思是 ANYCHILD。像/viewNode/* 这样的XPath 将返回&lt;viewNode&gt; 以下的所有孩子。然后,您可以使用local-name() 对元素的名称做出反应。在下面的代码中,我向XPath 添加了一个substring 谓词,以便返回以短语element 开头的元素。这将返回&lt;element&gt;&lt;elementFilter&gt;,但会忽略&lt;input&gt;。试试看:

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)

【讨论】:

    猜你喜欢
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多