基于Ben Davis的出色响应
here,我创建了一个表值函数,该函数返回一个属性名称 – 值对列表,该列表基于本身的XML片段.它可以返回列表中所有属性名称 – 值对整个片段,当我想限制它只是根元素上的那些.我该怎么做?谢谢,从XQuery新手.
INSERT INTO @attributeList SELECT DISTINCT CAST(attribute.name.query('local-name(.)') AS VARCHAR(100)),attribute.name.value('.','NVARCHAR(MAX)') FROM @xml.nodes('//@*') attribute(name)
ETA:经过一些实验证明,选择器’node()/ @ *’可以工作.感谢那些帮忙的人
我正在使用一个简单的数据迁移应用程序或数据泵前端Sitecore.我已经编写了一个可以在.NET中使用POCO对象并将其存入Sitecore的实用程序,但现在构建了迁移和日志记录数据库.源对象作为XML存储在一个地方.再次感谢你.
解决方法
这个问题已经在评论中得到回答,所以这只是一个解释的汇编.
对于实验,我们将使用这个XML:
DECLARE @XML XML = '<root root_attr="0"> <leaf leaf_attr="1">one</leaf> <brunch brunch_attr="2"> <leaf leaf_attr="3">three</leaf> </brunch> </root>';
我们需要提取根元素属性的列表:root_attr =“0”.
对于XPath参考,我们参考MSDN XPath Syntax guide
所以,“/”代表“子”或“根节点”,如果出现在模式的开头,“@”代表“属性”,“*”代表“任何”和“”.代表“当前上下文”.当然这应该给我们所有的根本属性:
SELECT CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],'NVARCHAR(MAX)') As [Value] FROM @XML.nodes('/@*') attribute(name);
而是会出现错误:不支持顶级属性节点.
XML中有两种类型的节点:< element>元素值< / element>和< element属性=“属性值”/> ;.因此,/ @ * XPath被解释为XML的根的任何属性,而不是根元素.其实可以说明如下:
SELECT CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],'NVARCHAR(MAX)') As [Value] FROM @XML.nodes('/') attribute(name);
返回:
Name Value ---- -------- onethree
哪个是代表整个XML文档的匿名节点. ” XPath会给出相同的结果.
好的,所以我们需要在XML文档的根目录中指定任何元素.该语法应该是“//”(匿名根节点=子元素的子代),因为此表达式不代表“递归下降”(所有子节点).确实
SELECT CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],'NVARCHAR(MAX)') As [Value] FROM @XML.nodes('//@*') attribute(name);
返回所有元素的完整属性列表:
Name Value ----------- -------- root_attr 0 leaf_attr 1 brunch_attr 2 leaf_attr 3
好的,现在我们需要一个在XPath中使用“root”“元素”的方式,而不是“rootelement”,这显然是一个保留字.一种方法是挤压“任何”,另一种方法是指定它应该是“node()”,除非我们知道根元素的实际名称.
对于给定的XML,这三个是相等的:
SELECT CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],'NVARCHAR(MAX)') As [Value] FROM @XML.nodes('/*/@*') attribute(name); SELECT CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],'NVARCHAR(MAX)') As [Value] FROM @XML.nodes('/node()/@*') attribute(name); SELECT CAST(attribute.name.query('local-name(.)') AS VARCHAR(MAX)) As [Name],'NVARCHAR(MAX)') As [Value] FROM @XML.nodes('/root/@*') attribute(name);
返回:
Name Value --------- -------- root_attr 0
我们在那里一些XPath重言式可以围绕“//”保留字.