搜索没有*给定子元素的元素*(子元素是可变的)

时间:2014-06-15 16:41:27

标签: sql-server xml xquery

在SQL Server 2008中,我希望在子元素名称为动态的情况下识别不包含给定子元素的元素。在此XML中,所有三个 li 元素都包含 F1 F2 子元素,第二个和第三个 li &#39 ; s不包含 edge 元素。如果事先知道 edge 元素的名称,我可以找到没有 edge 子元素的 li ,请参阅下面存在查询,它应该返回1。

declare @x xml = '<data>
  <li>
    <F1>ellipse</F1>
    <F2 />
    <edges/>
  </li>
  <li>
    <F1>triangle</F1>
    <F2>3</F2>
  </li>
  <li>
    <F1>square</F1>
    <F2>4</F2>
  </li>
</data>';

select @x.exist('/data/li[not(F1)]') -- returns 0, there is no li without an F1 (OK)
select @x.exist('/data/li[not(edges)]') -- returns 1, there is an li without edges (OK)

但如果事先不知道 edge 值,我该如何使用SQL变量指定它?我想编写如下代码:

declare @ChildElement varchar(100) = 'edges';
select @x.exist('/data/li[not(sql:variable("@ChildElement"))]') -- not allowed

但是SQL Server中的sql:variable在此上下文中无效。我也尝试过使用local-name():

select @x.exist('/data/li[not(local-name()=sql:variable("ChildElement"))]') -- always returns 1

但它总是返回1.我认为因为总有一个 li ,其子元素不是 F1 ,并且始终有 li < / strong>包含不是的子元素。如果 edge 在SQL变量中,如何只识别 li 而没有 edge 子元素? BTW我正在使用SQL Server 2008,虽然我认为这适用于2005年以后的所有SQL Server版本。

1 个答案:

答案 0 :(得分:3)

猜测你的第一种方法不起作用,因为变量被字符串“替换”(我不知道SQL Server的XQuery功能是否足以解释详细情况)

第二种方法是查询所有li元素,其中li元素的local-name()(当前上下文!)等于SQL变量 - 可能不是你想要做的。相反,尝试

select @x.exist('/data/li[not(./*[local-name()=sql:variable("@ChildElement")])]')

代替测试所有孩子。