November 29, 2012 at 7:29 am
Hi all,
I have the following XML stroed in a table colum.
I need to see all the following XML information in two rows (2 Row nodes).
<comments_data>
<Row>
<id>204506806280354_433001873430845_1108251</id>
<from>
<name>Francis Champs</name>
<id>100003216904024</id>
</from>
<message>Please help :)</message>
<message_tags>
<Row>
<id>64547938</id>
<name>John</name>
<type>user</type>
<offset>7</offset>
<length>14</length>
</Row>
</message_tags>
<created_time>2012-01-21T09:20:29+0000</created_time>
<likes>1</likes>
</Row>
<Row>
<id>204506806280354_433001873430845_1108329</id>
<from>
<name>Joseph</name>
<id>6473938</id>
</from>
<message>Thanks for the time :-D</message>
<created_time>2012-11-21T11:09:44+0000</created_time>
</Row>
</comments_data>
I used the partial query but did not return the desired results...
SELECT DISTINCT
T.ID AS PostID,
S.N.value('name[1]', 'varchar(150)') AS UserName,
S.N.value('id[1]', 'varchar(150)') AS UserID
FROM
(SELECT ID, CAST(CommentsData AS XML) CommentsData
FROM tb_Posts) AS T
CROSS APPLY T.CommentsData.nodes('/comments_data/Row/id/from') AS S(N)
Can anyone assist please?
Much appreciated,
Jon
November 29, 2012 at 7:35 am
Looks like a typo
CROSS APPLY T.CommentsData.nodes('/comments_data/Row/id/from') AS S(N)
should be
CROSS APPLY T.CommentsData.nodes('/comments_data/Row/from') AS S(N)
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537November 29, 2012 at 7:39 am
I guess the main problem is in xQuery, you shouldn't have "id " in it:
nodes('/comments_data/Row/from') AS S(N)
Check this:
declare @CommentsData xml =
'<comments_data>
<Row>
<id>204506806280354_433001873430845_1108251</id>
<from>
<name>Francis Champs</name>
<id>100003216904024</id>
</from>
<message>Please help :)</message>
<message_tags>
<Row>
<id>64547938</id>
<name>John</name>
<type>user</type>
<offset>7</offset>
<length>14</length>
</Row>
</message_tags>
<created_time>2012-01-21T09:20:29+0000</created_time>
<likes>1</likes>
</Row>
<Row>
<id>204506806280354_433001873430845_1108329</id>
<from>
<name>Joseph</name>
<id>6473938</id>
</from>
<message>Thanks for the time </message>
<created_time>2012-11-21T11:09:44+0000</created_time>
</Row>
</comments_data>
'
SELECT DISTINCT
S.N.value('name[1]', 'varchar(150)') AS UserName,
S.N.value('id[1]', 'varchar(150)') AS UserID
FROM @CommentsData.nodes('/comments_data/Row/from') AS S(N)
November 29, 2012 at 7:44 am
Actually yes I had a typo :s
I have created the following XQUERY and seems to work well.. Any further suggestions maybe I can enhance the query?
SELECT DISTINCT
T.ID AS PostID,
D.N.value('name[1]', 'varchar(150)') AS UserName,
D.N.value('id[1]', 'varchar(150)') AS UserID,
C.N.value('.[1]', 'varchar(150)') AS [Message],
E.N.value('.[1]', 'varchar(150)') AS CreatedTime,
F.N.value('.[1]', 'varchar(150)') AS Likes
FROM
(SELECT ID, CAST(CommentsData AS XML) CommentsData
FROM tb_Posts) AS T
CROSS APPLY T.CommentsData.nodes('/comments_data/Row') AS S(N)
OUTER APPLY S.N.nodes('message') AS C(N)
OUTER APPLY S.N.nodes('from') AS D(N)
OUTER APPLY S.N.nodes('created_time') AS E(N)
OUTER APPLY S.N.nodes('likes') AS F(N)
November 29, 2012 at 7:51 am
You don't need to OUTER APPLY, just use relative xPath:
SELECT DISTINCT
S.N.value('name[1]', 'varchar(150)') AS UserName,
S.N.value('id[1]', 'varchar(150)') AS UserID,
S.N.value('../message[1]', 'varchar(150)') AS [Message],
S.N.value('../from[1]', 'varchar(150)') AS [From],
S.N.value('../created_time[1]', 'varchar(150)') AS [CreatedTime],
S.N.value('../likes[1]', 'varchar(150)') AS [Likes]
FROM ...
November 29, 2012 at 8:01 am
Excellent Eugene Elutin,
Thanks very much!
November 30, 2012 at 1:20 am
Hi guys,
I am getting the error message:
XML parsing: line 7, character 411, illegal name character
just because I have characters like &, <, > in the data of the XML values.
Are there any solutions to this? Maybe something similar to UrlEscape for link?
I tried
SELECT ID, CAST( REPLACE(CommentsData, '>', '') AS XML) CommentsData
FROM tb_Posts
but of course this deform the resultant XML
Cheers,
Jon
November 30, 2012 at 3:04 am
& (and some other) characters in XML needs to be escaped (eg. & for &).
Otherwise, any XML parser will reject it as not well-formed XML...
November 30, 2012 at 3:36 am
Hi Eugene,
How can I escape the special characters (<, >, &) in XQUERY and successfully parse the XML ? The unfortunate thing is that I cannot ask the source to forward the XML without these special characters.
Thanks
Jon
November 30, 2012 at 3:57 am
Jonathan Mallia (11/30/2012)
Hi Eugene,How can I escape the special characters (<, >, &) in XQUERY and successfully parse the XML ? The unfortunate thing is that I cannot ask the source to forward the XML without these special characters.
Thanks
Jon
From computer perspective, if your text contains un-escapped xml special characters, this text is not XML! Try this:
declare @xmldata1 xml = '<mydata>Bla Bla Bla</mydata>'
and then this:
declare @xmldata2 xml = '<mydata>Bla & Bla Bla</mydata>'
You can see that the second one failed to assign the text to a variable of XML type.
Now, you may have a real problem, as the only way to fix it is in a process which inserts data into your table! You cannot use REPLACE in sql to escape "<" and ">". It will destroy xml tags.
So, change the source table column definition to XML (instead of text/varchar) and make sure when something is inserted there is real XML, not just XML looking text.
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply