Convert Plain Text to HTML - sql

I am having HTML code text as
select prd_desc from prd_mst
prd_desc
------------------------------------------------
<u>hello</u> <font color="#cc0000">dfgfdg</font>
How can i make it format in a HTML as 'hello...'
I am using replace function for all those special HTML characters or sqlserver has some shortcut, function for it.

You can use the XML datatype for this.
If you cast your value to XML that will give you a XML fragment that consists of one text element only. Extract that value using the value() function and you have a string that is not entitized.
select cast(p.prd_desc as xml).value('text()[1]', 'nvarchar(max)') as prd_desc
from dbo.prd_mst as p
Result:
prd_desc
-------------------------------------------------
<u>hello</u> <font color="#cc0000">dfgfdg</font>

Try this,
create FUNCTION udf_HtmlDecode
(
#UnDecoded as varchar(max)
)
RETURNS varchar(500)
AS
BEGIN
--declare #UnDecoded as varchar(500);
--set #UnDecoded = 'xvfxv <u>cbgdfgd</u> <font color="#cc0000">dfgfdg</font> <b>gdfgdf</b><br>';
DECLARE #Encoded as varchar(max)
--order is important here. Replace the amp first, then the lt and gt.
--otherwise the &lt will become &lt;
SELECT #Encoded = Replace(
Replace(
Replace(
Replace(#UnDecoded,'&','&'),
'<', '<'),
'>', '>'),
'"','"')
RETURN #Encoded
--select #Encoded
END
then execute
select dbo.udf_HtmlDecode('<u>hello</u> <font color="#cc0000">dfgfdg</font>')
will return
<u>hello</u> <font color="#cc0000">dfgfdg</font>

Related

SQL - Define/Modify XML with variables

I'm trying to define an XML variable with VARCHAR characters inside of it...
Example
DECLARE #number nvarchar(10);
SET #number = '10'
DECLARE #xml XML;
SET #xml =
'
<Root>
<Node> Hello {sql:variable("#number")} </Node>
</Root>
'
However, the problem is that you can only set xml variables to string literals. Is there any way of doing this? Thanks!
Not sure why you want to do this. Use + to concatenate the variable inside the string then assign it to xml varibale
DECLARE #number NVARCHAR(10);
SET #number = '10'
DECLARE #xml XML;
SET #xml = '
<Root>
<Node> Hello ' + Isnull(#number,'') + ' </Node>
</Root>
'
To view the xml
select #xml
Result :
<Root>
<Node> Hello 10 </Node>
</Root>
DECLARE #number nvarchar(10) = '10';
DECLARE #xml XML = N'';
SELECT #xml = #xml.query('
<Root>
<Node>Hello {sql:variable("#number")}</Node>
</Root>
');
SELECT #xml;
/*
<Root>
<Node>Hello 10</Node>
</Root>
*/
In my eyes the existing answers (upvoted and accepted) are no good paths to go. One should (almost) never create XML via string concatenation...
Why not the simple way? Let the XML-engine do the hard work!
DECLARE #number nvarchar(10);
SET #number = '10'
DECLARE #xml XML=(SELECT 'Hello ' + #number FOR XML PATH('Node'),ROOT('Root'),TYPE);
SELECT #xml;
Returns
<Root>
<Node>Hello 10</Node>
</Root>
Just imagine, your (string!) variable includes some text with forbidden characters (><& or qoutes or one of the many special / far east / whatever characters)... Using FOR XML ... will implicitly do all the escaping for you...
One side effect: If your variable is NULL you will not get a NULL for all, but a valid XML with an empty node:
<Root>
<Node />
</Root>

How to extract specific string part from the SQL String variable

I have an Sql Variable which contains a string value and want to extract specific part from that string value,
Declare #val as nvarchar(1000),
#outval as nvarchar(1000)
set #val='<Message>
<Header>
<MessageID>000000015</MessageID>
<MessageType>QualityData</MessageType>
<Sender>Data</Sender>
<Recipient>Data1</Recipient>
<PublishedDate>2013-12-22T13:15:23</PublishedDate>
</Header>
<Body>
<ID>150105</ID>
<Data>
<Count>5</Count>
<Brix>110</Brix>
<CO2>110</CO2>
</QualityData>
</Body>
</Message>'
Now i need to extract string from to using sql query. Output should be like as below.
<Body>
<ID>150105</ID>
<Data>
<Count>5</Count>
<Brix>110</Brix>
<CO2>110</CO2>
</Data>
</Body>
any suggestion to get this format using SQL Server.
This query may help you:
Declare #val as nvarchar(1000),
#outval as nvarchar(1000),
#start as int,
#end as int,
#len as int
set #val='<Message>
<Header>
<MessageID>000000015</MessageID>
<MessageType>QualityData</MessageType>
<Sender>Data</Sender>
<Recipient>Data1</Recipient>
<PublishedDate>2013-12-22T13:15:23</PublishedDate>
</Header>
<Body>
<ID>150105</ID>
<Data>
<Count>5</Count>
<Brix>110</Brix>
<CO2>110</CO2>
</QualityData>
</Body>
</Message>'
select #val= REPLACE(#val,'<Message>','');
select #val= REPLACE(#val,'</Message>','');
SELECT #start= CHARINDEX('<Body>', #val);
SELECT #end=CHARINDEX('</Body>', #val);
select #len= LEN (#val)
SELECT #outval= SUBSTRING ( #val ,#start ,#end- #start )
print #outval
Use a substring to extract the information and patindex to find the start character and length as below:
Select Substring(#val,PATINDEX('%<body>%', #val),PATINDEX('%</body>%', #val) - PATINDEX('%<body>%', #val) + 7)
Following your statements, I added the below line to your code. I have used the SUBSTRING and CHARINDEX in my case to solve this one, and I got exactly what you are looking for. Here is my Code: SELECT SUBSTRING(#VAL, CHARINDEX('<Body>', #VAL), CHARINDEX('</QualityData>', #VAL) - CHARINDEX('<Body>', #VAL) + LEN('</QualityData>')) This worked fine for me.

Convert to XML having special character name in SQL server

There is a XML in the below format present in a column of datatype VARCHAR(MAX) in sql table
<?xml version="1.0" encoding="UTF-8"?>
<APIDATA xmlns="mynamespace">
<TRADE Action="Insert" CompanyID="33" Trader="Aleš Holubec"
</TRADE>
</APIDATA>
I need to fetch attribute values of Action and CompanyID . i.e, Insert and 33
In SQL, i used the below query
;WITH XMLNAMESPACES(DEFAULT 'mynamespace')
SELECT CONVERT(XML,column_name).value ('(APIDATA/TRADE/#Action)[1]', 'varchar(100)')
But i get the below error
XML parsing: line 1, character 537, illegal xml character
The reason is Aleš Holubec is the name of the trader in the XML which we cannot change.
Please help how to resolve this
You can fix this by converting your string to nvarchar(max) and then replace the encoding to UTF-16.
;WITH XMLNAMESPACES(DEFAULT 'mynamespace')
SELECT CONVERT(XML, replace(cast(column_name as nvarchar(max)), '<?xml version="1.0" encoding="UTF-8"?>', '<?xml version="1.0" encoding="UTF-16"?>')).value ('(APIDATA/TRADE/#Action)[1]', 'varchar(100)')
Or you can just remove the XML declaration.
;WITH XMLNAMESPACES(DEFAULT 'mynamespace')
SELECT CONVERT(XML, replace(column_name, '<?xml version="1.0" encoding="UTF-8"?>', '')).value ('(APIDATA/TRADE/#Action)[1]', 'varchar(100)')
I ran into the same issue with special characters and XML. Below is an example of what I did to resolve the problem with working code that you will need to modify for your DB.
The only thing I needed C# to handle for me was the single quote. C# will need to change the single quote to &apos; before sending it as a CSV list, if not it will fail.
Hope this helps..
/**************************************************************************************
**************************************************************************************
***
*** This is to demonstrate how to use XML in SQL statements.
*** C# must send the the list of items in comma seperated values and
*** replace the character Single Quote with &apos; or the SQL statement
*** will fail. This is the only character that SQL can not handle when sent as a
*** string.
***
*** The steps below will explain each part and how it handles special
*** characters in XML and turns them into a temp table.
***
***
**************************************************************************************
**************************************************************************************/
SET ARITHABORT ON
DECLARE #CUST_REF3 AS XML
DECLARE #CSharpString AS NVARCHAR(MAX)
--This is used for when the CSV string is passed in normally.
SET #CSharpString = ISNULL('{0}', '')
--Example of when the CSV string is passed in and it having a special characters.
SET #CSharpString = 'SHOP A, LA WHEEL & BRAKE SHOP, SHOP&apos;s B'
--Example of when nothing is passed in from C#
--SET #CSharpString = ''
--Replaces any special character for preperation of XML formating
SET #CSharpString = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(#CSharpString,'&', '&'),'<', '<'),'>', '>'),'"', '"'),'''', '&apos;')
-- Turn the #CSharpString (CSV) into XML
SET #CUST_REF3 = CAST('<A>'+ NULLIF(REPLACE(#CSharpString, N',', '</A><A>'), '') + '</A>' AS XML)
--Display the converted XML list
SELECT #CUST_REF3
--Converts the XML nodes into a temp table. Make sure the data type is set correctly for the data being received.
SELECT dbo.Trim(CUST_REF3.value('.','nchar(22)')) AS [CUST_REF3]
INTO #XML_List
FROM #CUST_REF3.nodes('/A') AS x(CUST_REF3)
--Display what Converted list
SELECT * FROM #XML_List
--example of output from the C# String
SELECT USER_DOC, CUST_REF3
FROM dbo.WO_HDR
WHERE
--This matches the list of items sent from C#
((SELECT TOP(1) x.CUST_REF3
FROM #XML_List x
WHERE x.CUST_REF3 = dbo.WO_HDR.CUST_REF3) IS NOT NULL OR
--If the user did not select anything, do not filter
#CSharpString = '')
--Dispose of temp table
IF OBJECT_ID('tempdb..#XML_List') IS NOT NULL
DROP TABLE #XML_List
/**********************************************************************************************************************************************************
--Summerized code to use:
SET ARITHABORT ON
DECLARE #CUST_REF3 AS XML
DECLARE #CSharpString AS NVARCHAR(MAX)
SET #CSharpString = ISNULL('{0}', '')
SET #CSharpString = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(#CSharpString,'&', '&'),'<', '<'),'>', '>'),'"', '"'),'''', '&apos;')
SET #CUST_REF3 = CAST('<A>'+ NULLIF(REPLACE(#CSharpString, N',', '</A><A>'), '') + '</A>' AS XML)
SELECT dbo.Trim(CUST_REF3.value('.','nchar(22)')) AS [CUST_REF3] INTO #XML_List FROM #CUST_REF3.nodes('/A') AS x(CUST_REF3)
--Add this scring to every WHERE statment you want this filter to be used.
--((SELECT TOP(1) x.CUST_REF3 FROM #XML_List x WHERE x.CUST_REF3 = dbo.WO_HDR.CUST_REF3) IS NOT NULL OR #CSharpString = '')
IF OBJECT_ID('tempdb..#XML_List') IS NOT NULL DROP TABLE #XML_List
**********************************************************************************************************************************************************/

How to decode & etc using XQuery/SQL?

Using Microsoft SQL Server...
declare #x xml
set #x = '<Example><You & Me></Example>'
select cast(#x.query('/Example/text()') as nvarchar(50))
The result is "<You & Me>" rather than "<You & Me>".
How can I have SQL read the XML in such as way that '<', '&' and '>' are decoded?
Use value() instead of query().
declare #x xml
set #x = '<Example><You & Me></Example>'
select #x.value('(/Example)[1]', 'nvarchar(50)')
SQL-Fiddle

T-SQL select all XML nodes as rows from RDL data

I'm trying to SELECT from a table containing XML column. I would like to obtain specific node and have a row created for each one.
The XML is directly obtained from Reporting Services database and contains RDL (report) structure. My goal is to display all ‹Textbox›‹Value›example‹/Value›‹/Textbox› values for each report. The location of ‹Textbox› nodes is unpredictable (it can be part of any element somewhere in XML structure).
Below is the current code, but for some reason id doesn't work:
IF object_id('tempdb..#c') IS NOT NULL
DROP TABLE #c
select top 50
path as reportpath
,name as reportname
,convert(xml, convert(varbinary(max), content)) as reportxml
into
#c
from
reportserver.dbo.catalog
where
content is not null
order by creationdate desc
-----------------------------------------
DECLARE #x XML
SELECT #x =
( SELECT
[reportpath]
,[reportname]
,[reportxml].query('
for $a in //../Textbox
return ‹Textbox
valueX="{$a/Value}"
/›
')
FROM #c AS reports
FOR XML AUTO
)
select #x
-----------------------------------------
SELECT [reportpath] = T.Item.value('../#reportpath', 'nvarchar(max)'),
[reportname] = T.Item.value('../#reportname', 'nvarchar(max)'),
value = T.Item.value('#value' , 'nvarchar(max)')
FROM #x.nodes('//reports/Textbox') AS T(Item)
Example below shows sample "Textbox" containg a "Value":
‹RowGrouping›
‹Width›2.53968cm‹/Width›
‹DynamicRows›
‹Grouping Name="matrix1_OperationalWeek2"›
‹GroupExpressions›
‹GroupExpression›=Fields!OperationalWeek.Value‹/GroupExpression›
‹/GroupExpressions›
‹/Grouping›
‹ReportItems›
‹Textbox Name="textbox35"›
‹rd:DefaultName›textbox35‹/rd:DefaultName›
‹Style›
‹BackgroundColor›White‹/BackgroundColor›
‹PaddingLeft›2pt‹/PaddingLeft›
‹PaddingRight›2pt‹/PaddingRight›
‹PaddingTop›2pt‹/PaddingTop›
‹PaddingBottom›2pt‹/PaddingBottom›
‹/Style›
‹ZIndex›8‹/ZIndex›
‹Value›=Fields!OperationalWeek.Value‹/Value›
‹/Textbox›
‹/ReportItems›
‹/DynamicRows›
‹/RowGrouping›
PS I had some trouble with stackoverflow code formatting so I replaced < and > marks with ‹ and ›. Sorry about that.
Based on Bret's Blog ([http://blogs.netconnex.com/2011/05/extracting-ssrs-report-rdl-xml-from.html][1])
and adding the namespace gets you results... I wish I could claim I understand well enough to explain but I mostly find my way by "stumbling" through it.
--================================================
;WITH XMLNAMESPACES (
DEFAULT 'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition',
'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS rd --ReportDefinition
)
select top 50
c.Path as reportpath
--, c.name as reportname
,t.value('#Name','VARCHAR(100)') as TextboxName
,t.value('data(Paragraphs/Paragraph/TextRuns/TextRun/Value)[1]', 'varchar(max)') as value
from
reportserver.dbo.catalog c
cross apply
(select convert(xml, convert(varbinary(max), content))) as R(reportxml)
cross apply
--Get all the Query elements (The "*:" ignores any xml namespaces)
r.reportxml.nodes('//*:Textbox') n(t)
where
content is not null
and c.Type = 2 -- Reports
order by creationdate desc
This simple XQuery:
for $a in //Textbox
return
<Textbox
valueX="{$a/Value}"
/>
when applied on the provided XML document (namespace definition added to make it well-formed):
<RowGrouping xmlns:rd="rd">
<Width>2.53968cm</Width>
<DynamicRows>
<Grouping Name="matrix1_OperationalWeek2">
<GroupExpressions>
<GroupExpression>=Fields!OperationalWeek.Value</GroupExpression>
</GroupExpressions>
</Grouping>
<ReportItems>
<Textbox Name="textbox35">
<rd:DefaultName>textbox35</rd:DefaultName>
<Style>
<BackgroundColor>White</BackgroundColor>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
<ZIndex>8</ZIndex>
<Value>=Fields!OperationalWeek.Value</Value>
</Textbox>
</ReportItems>
</DynamicRows>
</RowGrouping>
produces the wanted, correct result:
<?xml version="1.0" encoding="UTF-8"?>
<Textbox valueX="=Fields!OperationalWeek.Value"/>
Therefore, if you cannot get result, your problem is in something else, not in the XQuery code.
I can't test if this works but it should do what you want.
select top 50
path as reportpath
,name as reportname
,n.t.value('Value[1]', 'varchar(max)') as value
from
reportserver.dbo.catalog
cross apply
(select convert(xml, convert(varbinary(max), content))) as c(reportxml)
cross apply
c.reportxml.nodes('//Textbox') n(t)
where
content is not null
order by creationdate desc