【发布时间】:2014-03-24 01:24:07
【问题描述】:
我必须抓取给定 XML 的元素,为每个元素生成 xpath,然后检索每个元素的值:
我可以创建第一步和第二步,但是当元素具有属性时,XPATH 不起作用:
所以如果我有以下 XPATH:
/Envelope[1]/Body[1]/sVerify[1]/verifyPost[1]/Message[1]/Error[1]
/Envelope[1]/Body[1]/sVerify[1]/verifyPost[1]/scope[1]/machine[1]/space[1]
/Envelope[1]/Body[1]/sVerify[1]/verifyPost[1]/scope[1]/Date[1]
它适用于Below XML,并且能够正确获取元素值:
-- Works: I can retrieve the Elements values using XPATH
<Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<sVerify>
<verifyPost>
<scope>
<machine>
<name>test</name>
<space>test2</space>
</machine>
<Sys>internal</Sys>
<Date>2013-02-28</Date>
</scope>
<Message>
<Error>11111111111</Error>
<Descrip>222222222</Descrip>
</Message>
<Final>true</Final>
<Receipt>33333</Receipt>
</verifyPost>
</sVerify>
</Body>
</Envelope>
请注意,我必须手动删除所有属性才能使 XPATH 正常工作。如果 XML 如下所示,则它不起作用:
-- Doesn't work: can't get the elements value
<Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<sVerify xmlns="http://www.myCompany.com/Location/2014">
<verifyPost>
<scope>
<machine xmlns:i="http://www.myCompany.com/Location/2014">
<name>test</name>
<space>test2</space>
</machine>
<Sys>internal</Sys>
<Date>2013-02-28</Date>
</scope>
<Message xmlns="http://www.myCompany.com/Location/2014">
<Error>11111111111</Error>
<Descrip>222222222</Descrip>
</Message>
<Final xmlns="http://www.myCompany.com/Location/2014">true</Final>
<Receipt>33333</Receipt>
</verifyPost>
</sVerify>
</Body>
</Envelope>
可以有任意数量的属性,所以我永远不知道这些属性会是什么。确保 XPATH 始终找到给定元素的值的正确方法是什么,无论它是否具有属性。
以下是我在 TSQL 中的执行方式:
DECLARE @generatedXPATH nvarchar(500),
@elementVal nvarchar(50),
@xml xml,
@query nvarchar(max)
-- it works with this payload
-- because attributes aren't there replacing it with xml
-- where element attributes are present fails the element value extraction using xpath
SET @xml = '<Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <sVerify> <verifyPost> <scope> <machine> <name>test</name> <space>test2</space> </machine> <Sys>internal</Sys> <Date>2013-02-28</Date> </scope> <Message> <Error>11111111111</Error> <Descrip>222222222</Descrip> </Message> <Final>true</Final> <Receipt>33333</Receipt> </verifyPost> </sVerify> </Body> </Envelope>'
SET @generatedXPATH = '/Envelope[1]/Body[1]/sVerify[1]/verifyPost[1]/scope[1]/machine[1]/space[1]'
SET @elementVal = ''
SET @query = N'SELECT @elementVal= Nodes.node.value(''(' + @generatedXPATH
+ ')[1]'', ''varchar(50)'') FROM @xml.nodes(''.'') AS Nodes(node)';
exec sp_ExecuteSql
@query,
N' @xml xml,@elementVal nvarchar(max) output',
@xml = @xml,
@elementVal = @elementVal output
select @elementVal
更新:
似乎只有属性为 without 前缀的属性会导致问题。例如,如果属性是xlmns="...........",那么我无法使用 XPATH 获取它的值,如果属性是 xlmns:i=".........." 那么它似乎可以工作。不知道发生了什么。
【问题讨论】:
标签: sql sql-server sql-server-2008 tsql sqlxml