I have a TEXT datatype field called "XMLText" in SQL Server 2012. What I'd like to do is remove any SageID fields. So this long string field contains something that looks like this:
<pair n="priorinstitution2" v="Yale School of Medicine" />
<pair n="priorinstitution3" v="" />
<pair n="sageid" v="20668528" />
<pair n="priorinstitution1" v="University of Chicago" />
What I'd like to do is remove everything for the SageID tag so that the final result is this:
<pair n="priorinstitution2" v="Yale School of Medicine" />
<pair n="priorinstitution3" v="" />
<pair n="priorinstitution1" v="University of Chicago" />
Obviously, it's not in a fixed position in the field and the v= could be any numbers or length. What's the SQL string manipulation to do this?
TEXT is deprecated. Store your XML chunks as XML or NVARCHAR(MAX).
You can use xml.modify and delete to remove multiple occurences at once:
CREATE TABLE #tab(id INT, col TEXT);
INSERT INTO #tab(id, col)
VALUES
(1, '<pair n="priorinstitution2" v="Yale School of Medicine" />
<pair n="priorinstitution3" v="" />
<pair n="sageid" v="20668528" />
<pair n="priorinstitution1" v="University of Chicago" />')
,(2, '<pair n="sageid" v="2" y="adsadasdasd"/>
<pair n="priorinstitution2" v="Yale School of Medicine" />
<pair n="priorinstitution3" v="" />
<pair n="sageid" v="20668528" />
<pair n="priorinstitution1" v="University of Chicago" />
<pair n="sageid" v="2066852832421432" z="aaaa" />');
SELECT *, xml_col = CAST(col AS XML)
INTO #temp
FROM #tab;
UPDATE #temp
SET xml_col.modify('delete /pair[#n="sageid"]');
UPDATE t1
SET col = CAST(t2.xml_col AS NVARCHAR(MAX))
FROM #tab t1
JOIN #temp t2
ON t1.id = t2.id;
SELECT *
FROM #tab;
LiveDemo
Keep in mind that your XML data is not well-formed (no root element).
EDIT:
If your XML Text has different structure and you want to find all pair element with attribute n="sageid" use:
UPDATE #temp
SET xml_col.modify('delete //pair[#n="sageid"]');
LiveDemo2
Not a great solution but to find positions of start and end of tag and replace it with a blank string
UPDATE YourTable
SET yourColumn = REPLACE(yourColumn, SUBSTRING(yourColumn, CHARINDEX('<pair n="sageid"', yourColumn), CHARINDEX('/>', yourColumn, CHARINDEX('<pair n="sageid"', yourColumn)) - CHARINDEX('<pair n="sageid"', yourColumn) + 2), '')
Adding below script for debugging
DECLARE #str AS VARCHAR(255) = '<pair n="priorinstitution2" v="Yale School of Medicine" /><pair n="priorinstitution3" v="" /><pair n="sageid" v="20668528" /><pair n="priorinstitution1" v="University of Chicago" />'
SELECT REPLACE(#str, SUBSTRING(#str, CHARINDEX('<pair n="sageid"', #str), CHARINDEX('/>', #str, CHARINDEX('<pair n="sageid"', #str)) - CHARINDEX('<pair n="sageid"', #str) + 2), '')
Related
I have this xml file (it's called "LogReg.xml" and it contains some information about a logistic regression (I am interested in the name of the features and their coefficient - I'll explain in more detail below):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PMML xmlns="http://www.dmg.org/PMML-4_4" xmlns:data="http://jpmml.org/jpmml-model/InlineTable" version="4.4">
<Header>
<Application name="JPMML-SkLearn" version="1.6.35"/>
<Timestamp>2022-02-15T09:44:54Z</Timestamp>
</Header>
<MiningBuildTask>
<Extension name="repr">PMMLPipeline(steps=[('classifier', LogisticRegression())])</Extension>
</MiningBuildTask>
<DataDictionary>
<DataField name="Target" optype="categorical" dataType="integer">
<Value value="0"/>
<Value value="1"/>
</DataField>
<DataField name="const" optype="continuous" dataType="double"/>
<DataField name="grade" optype="continuous" dataType="double"/>
<DataField name="emp_length" optype="continuous" dataType="double"/>
<DataField name="dti" optype="continuous" dataType="double"/>
<DataField name="Orig_FicoScore" optype="continuous" dataType="double"/>
<DataField name="inq_last_6mths" optype="continuous" dataType="double"/>
<DataField name="acc_open_past_24mths" optype="continuous" dataType="double"/>
<DataField name="mort_acc" optype="continuous" dataType="double"/>
<DataField name="mths_since_recent_bc" optype="continuous" dataType="double"/>
<DataField name="num_rev_tl_bal_gt_0" optype="continuous" dataType="double"/>
<DataField name="percent_bc_gt_75" optype="continuous" dataType="double"/>
</DataDictionary>
<RegressionModel functionName="classification" algorithmName="sklearn.linear_model._logistic.LogisticRegression" normalizationMethod="logit">
<MiningSchema>
<MiningField name="Target" usageType="target"/>
<MiningField name="const"/>
<MiningField name="grade"/>
<MiningField name="emp_length"/>
<MiningField name="dti"/>
<MiningField name="Orig_FicoScore"/>
<MiningField name="inq_last_6mths"/>
<MiningField name="acc_open_past_24mths"/>
<MiningField name="mort_acc"/>
<MiningField name="mths_since_recent_bc"/>
<MiningField name="num_rev_tl_bal_gt_0"/>
<MiningField name="percent_bc_gt_75"/>
</MiningSchema>
<Output>
<OutputField name="probability(0)" optype="continuous" dataType="double" feature="probability" value="0"/>
<OutputField name="probability(1)" optype="continuous" dataType="double" feature="probability" value="1"/>
</Output>
<RegressionTable intercept="0.8064694059338298" targetCategory="1">
<NumericPredictor name="const" coefficient="0.8013433785974717"/>
<NumericPredictor name="grade" coefficient="0.9010481046582982"/>
<NumericPredictor name="emp_length" coefficient="0.9460686056314133"/>
<NumericPredictor name="dti" coefficient="0.5117062988491518"/>
<NumericPredictor name="Orig_FicoScore" coefficient="0.07944303372859234"/>
<NumericPredictor name="inq_last_6mths" coefficient="0.20516234445402765"/>
<NumericPredictor name="acc_open_past_24mths" coefficient="0.4852503249658917"/>
<NumericPredictor name="mort_acc" coefficient="0.6673203078463711"/>
<NumericPredictor name="mths_since_recent_bc" coefficient="0.1962158305958366"/>
<NumericPredictor name="num_rev_tl_bal_gt_0" coefficient="0.12964661294856686"/>
<NumericPredictor name="percent_bc_gt_75" coefficient="0.04534570018290847"/>
</RegressionTable>
<RegressionTable intercept="0.0" targetCategory="0"/>
</RegressionModel>
</PMML>
I have parsed it using this code:
from lxml import objectify
path = 'LogReg.xml'
parsed = objectify.parse(open(path))
root = parsed.getroot()
data = []
if True:
for elt in root.RegressionModel.RegressionTable:
el_data = {}
for child in elt.getchildren():
el_data[child.tag] = child.text
data.append(el_data)
perf = pd.DataFrame(data)
I am interested in parsing this bit:
<RegressionTable intercept="0.8064694059338298" targetCategory="1">
<NumericPredictor name="const" coefficient="0.8013433785974717"/>
<NumericPredictor name="grade" coefficient="0.9010481046582982"/>
<NumericPredictor name="emp_length" coefficient="0.9460686056314133"/>
<NumericPredictor name="dti" coefficient="0.5117062988491518"/>
<NumericPredictor name="Orig_FicoScore" coefficient="0.07944303372859234"/>
<NumericPredictor name="inq_last_6mths" coefficient="0.20516234445402765"/>
<NumericPredictor name="acc_open_past_24mths" coefficient="0.4852503249658917"/>
<NumericPredictor name="mort_acc" coefficient="0.6673203078463711"/>
<NumericPredictor name="mths_since_recent_bc" coefficient="0.1962158305958366"/>
<NumericPredictor name="num_rev_tl_bal_gt_0" coefficient="0.12964661294856686"/>
<NumericPredictor name="percent_bc_gt_75" coefficient="0.04534570018290847"/>
</RegressionTable>
so that I can build the following dictionary:
myDict = {
"const : 0.8013433785974717,
"grade" : 0.9010481046582982,
"emp_length" : 0.9460686056314133,
"dti" : 0.5117062988491518,
"Orig_FicoScore" : 0.07944303372859234,
"inq_last_6mths" : 0.20516234445402765,
"acc_open_past_24mths" : 0.4852503249658917,
"mort_acc" : 0.6673203078463711,
"mths_since_recent_bc" : 0.1962158305958366,
"num_rev_tl_bal_gt_0" : 0.12964661294856686,
"percent_bc_gt_75" : 0.04534570018290847
}
Basically, in the dictionary the Key is the name of the feature and the value is the coefficient of the logistic regression.
Please can anyone help me with the code?
I'm not sure you need pandas for this, but you do need to handle the namespaces in your xml.
Try something along these lines:
myDict = {}
#register the namespace
ns = {'xx': 'http://www.dmg.org/PMML-4_4'}
#you could collapse the next two into one line, but I believe it's clearer this way
rt = root.xpath('//xx:RegressionTable[.//xx:NumericPredictor]',namespaces=ns)[0]
nps = rt.xpath('./xx:NumericPredictor',namespaces=ns)
for np in nps:
myDict[np.attrib['name']]=np.attrib['coefficient']
myDict
The output should be your expected output.
I am working with some XML and I have an issue.
The xml looks like this:
<tagvalues>
<tagvalue>
<tag>Data.Barcode</tag>
<value>True</value>
</tagvalue>
<tagvalue>
<tag>Data.DateStampFirstScale</tag>
<value>20180111</value>
</tagvalue>
<tagvalue>
<tag>Data.DateStampLastScale</tag>
<value>20180111</value>
</tagvalue>
<tagvalue>
<tag>Data.Dot</tag>
<value>False</value>
</tagvalue>
<tagvalue>
<tag>Data.Hangtab</tag>
<value>False</value>
</tagvalue>
<tagvalue>
<tag>Data.Scale_x.Scale_0.Deviation</tag>
<value>0</value>
</tagvalue>
<tagvalue>
<tag>Data.Scale_x.Scale_0.DeviationHigh</tag>
<value>False</value>
</tagvalue>
<tagvalue>
<tag>Data.Scale_x.Scale_0.DeviationLimitHigh</tag>
<value>0</value>
</tagvalue>
</tagvalues>
and currently I'm getting the data with this code:
#data.value('/tagvalues[1]/tagvalue[3]/value[1]', 'nvarchar(100)')
The problem I'm having is that sometimes the order is changed, which means that I have to reconfigure it again.
Is it not possible to convert the XML text into an temp table like so:
Tag Value
--------------------------------------------------
Data.Barcode TRUE
Data.DateStampFirstScale 20180111
Data.DateStampLastScale 20180111
Data.Dot FALSE
Data.Hangtab FALSE
Data.Scale_x.Scale_0.Deviation 0
Data.Scale_x.Scale_0.DeviationHigh FALSE
Data.Scale_x.Scale_0.DeviationLimitHigh 0
Try the XQuery.. .nodes()
select n.value('tag[1]', 'varchar(max)') [Tag],
n.value('value[1]', 'varchar(max)') [Value]
from #xml.nodes('tagvalues/tagvalue') as p(n)
You mean like this?
DECLARE #XML xml;
SET #XML =
'<tagvalues>
<tagvalue>
<tag>Data.Barcode</tag>
<value>True</value>
</tagvalue>
<tagvalue>
<tag>Data.DateStampFirstScale</tag>
<value>20180111</value>
</tagvalue>
<tagvalue>
<tag>Data.DateStampLastScale</tag>
<value>20180111</value>
</tagvalue>
<tagvalue>
<tag>Data.Dot</tag>
<value>False</value>
</tagvalue>
<tagvalue>
<tag>Data.Hangtab</tag>
<value>False</value>
</tagvalue>
<tagvalue>
<tag>Data.Scale_x.Scale_0.Deviation</tag>
<value>0</value>
</tagvalue>
<tagvalue>
<tag>Data.Scale_x.Scale_0.DeviationHigh</tag>
<value>False</value>
</tagvalue>
<tagvalue>
<tag>Data.Scale_x.Scale_0.DeviationLimitHigh</tag>
<value>0</value>
</tagvalue>
</tagvalues>'
SELECT X.N.value('(tag/text())[1]','varchar(50)') AS Tag,
X.N.value('(value/text())[1]','varchar(50)') AS [Value]
FROM #XML.nodes('/tagvalues/tagvalue') X(N);
If found several questions about how to convert a table (or query) into XML, but none that showed how to start with one main table and join several one:many satellite tables, and from that generate XML that represents the hierarchical structure of the data. So I thought I'd share this solution now that I've figured it out. If someone else has another way of doing this, please post another answer.
Given this contrived data:
create table #recipe (id int, name varchar(10))
create table #ingredient (recipe_id int, name varchar(30), quantity varchar(20), sort int)
create table #instruction (recipe_id int, task varchar(32), sort int)
insert into #recipe values (1, 'pizza'), (2, 'omelet')
insert into #ingredient values (1, 'pizza dough', '1 package', 1),
(1, 'tomato sauce', '1 can', 2),
(1, 'favorite toppings', 'you choose', 3),
(2, 'eggs', 'three', 1),
(2, 'a bunch of other ingredients', 'you choose', 2)
insert into #instruction values (1, 'pre-bake pizza dough', 1),
(1, 'add tomato sauce', 2),
(1, 'add toppings', 3),
(1, 'bake a little longer', 4),
(2, 'break eggs into mixing bowl', 1),
(2, 'beat yolks and whites together', 2),
(2, 'pour into large sauce pan', 3),
(2, 'add other ingredients', 4),
(2, 'fold in half', 5),
(2, 'cook until done', 6)
.
Which looks like this in tabular form:
#recipe
id name
----------- ----------
1 pizza
2 omelet
.
#ingredient
recipe_id name quantity sort
----------- ------------------------------ -------------------- -----------
1 pizza dough 1 package 1
1 tomato sauce 1 can 2
1 favorite toppings you choose 3
2 eggs three 1
2 a bunch of other ingredients you choose 2
.
#instruction
recipe_id task sort
----------- -------------------------------- -----------
1 pre-bake pizza dough 1
1 add tomato sauce 2
1 add toppings 3
1 bake a little longer 4
2 break eggs into mixing bowl 1
2 beat yolks and whites together 2
2 pour into large sauce pan 3
2 add other ingredients 4
2 fold in half 5
2 cook until done 6
.
I want to create an XML document that has one record for each recipe, and within each recipe element, I want a group of ingredients and another group of instructions, like this:
<recipes>
<recipe id="2" name="omelet">
<ingredients>
<ingredient name="eggs" quantity="three" />
<ingredient name="a bunch of other ingredients" quantity="you choose" />
</ingredients>
<instructions>
<instruction task="break eggs into mixing bowl" />
<instruction task="beat yolks and whites together" />
<instruction task="pour into large sauce pan" />
<instruction task="add other ingredients" />
<instruction task="fold in half" />
<instruction task="cook until done" />
</instructions>
</recipe>
<recipe id="1" name="pizza">
<ingredients>
<ingredient name="pizza dough" quantity="1 package" />
<ingredient name="tomato sauce" quantity="1 can" />
<ingredient name="favorite toppings" quantity="you choose" />
</ingredients>
<instructions>
<instruction task="pre-bake pizza dough" />
<instruction task="add tomato sauce" />
<instruction task="add toppings" />
<instruction task="bake a little longer" />
</instructions>
</recipe>
</recipes>
This SQL creates the desired XML verbatim:
select recipe.*,
(
select ingredient.name, ingredient.quantity
from #ingredient ingredient
where recipe.id = ingredient.recipe_id
order by ingredient.sort
for xml auto, root('ingredients'), type
),
(
select instruction.task
from #instruction instruction
where recipe.id = instruction.recipe_id
order by instruction.sort
for xml auto, root('instructions'), type
)
from #recipe as recipe
order by recipe.name
for xml auto, root('recipes'), type
I aliased the temp table names because using for xml auto on temp tables creates poorly named XML elements. This is how it looks:
<recipes>
<recipe id="2" name="omelet">
<ingredients>
<ingredient name="eggs" quantity="three" />
<ingredient name="a bunch of other ingredients" quantity="you choose" />
</ingredients>
<instructions>
<instruction task="break eggs into mixing bowl" />
<instruction task="beat yolks and whites together" />
<instruction task="pour into large sauce pan" />
<instruction task="add other ingredients" />
<instruction task="fold in half" />
<instruction task="cook until done" />
</instructions>
</recipe>
<recipe id="1" name="pizza">
<ingredients>
<ingredient name="pizza dough" quantity="1 package" />
<ingredient name="tomato sauce" quantity="1 can" />
<ingredient name="favorite toppings" quantity="you choose" />
</ingredients>
<instructions>
<instruction task="pre-bake pizza dough" />
<instruction task="add tomato sauce" />
<instruction task="add toppings" />
<instruction task="bake a little longer" />
</instructions>
</recipe>
</recipes>
.
This SQL creates another version of the XML with all data as values instead of attributes, but in the same basic hierarchical structure:
select recipe.*,
(
select ingredient.name, ingredient.quantity
from #ingredient ingredient
where recipe.id = ingredient.recipe_id
order by ingredient.sort
for xml path('ingredient'), root('ingredients'), type
),
(
select instruction.task
from #instruction instruction
where recipe.id = instruction.recipe_id
order by instruction.sort
for xml path('instruction'), root('instructions'), type
)
from #recipe as recipe
order by recipe.name
for xml path('recipe'), root('recipes'), type
.
This is how it looks:
<recipes>
<recipe>
<id>2</id>
<name>omelet</name>
<ingredients>
<ingredient>
<name>eggs</name>
<quantity>three</quantity>
</ingredient>
<ingredient>
<name>a bunch of other ingredients</name>
<quantity>you choose</quantity>
</ingredient>
</ingredients>
<instructions>
<instruction>
<task>break eggs into mixing bowl</task>
</instruction>
<instruction>
<task>beat yolks and whites together</task>
</instruction>
<instruction>
<task>pour into large sauce pan</task>
</instruction>
<instruction>
<task>add other ingredients</task>
</instruction>
<instruction>
<task>fold in half</task>
</instruction>
<instruction>
<task>cook until done</task>
</instruction>
</instructions>
</recipe>
<recipe>
<id>1</id>
<name>pizza</name>
<ingredients>
<ingredient>
<name>pizza dough</name>
<quantity>1 package</quantity>
</ingredient>
<ingredient>
<name>tomato sauce</name>
<quantity>1 can</quantity>
</ingredient>
<ingredient>
<name>favorite toppings</name>
<quantity>you choose</quantity>
</ingredient>
</ingredients>
<instructions>
<instruction>
<task>pre-bake pizza dough</task>
</instruction>
<instruction>
<task>add tomato sauce</task>
</instruction>
<instruction>
<task>add toppings</task>
</instruction>
<instruction>
<task>bake a little longer</task>
</instruction>
</instructions>
</recipe>
</recipes>
Originally I tried placing the ingredients and instructions in the main query's from clause with an inner join to the recipe table. But the instructions were all nested within the ingredients, which were nested within the recipe. When I moved them up to the select part of the query it straightened out the XML.
im having this kind of xml:
<?xml version="1.0"?>
-<recordedData>
<machine>ZSK40-2</machine>
<date>2013/09/21</date>
<hour>05:32</hour>-<CollectedData>-<variable>
<Name>PRODUCT</Name>
<Value>FILLER 580</Value>
</variable>-<variable>
<Name>LOT_NUMBER</Name>
<Value>CG 00063 0</Value>
</variable>-<variable>
<Name>SHIFT_SUPERVISOR</Name>
<Value> covaliu l</Value>
</variable>-<variable>
<Name>KGH_ALL_SET</Name>
<Value>0</Value>
</variable>-<variable>
<Name>KGH_ALL_REAL</Name>
<Value>0</Value>
</variable>-<variable>
<Name>KGH_F1_SET</Name>
<Value>0</Value>
</variable>-<variable>
<Name>KGH_F1_REAL</Name>
<Value>0</Value>
</variable>-<variable>
<Name>K_F1</Name>
<Value>43</Value>
</variable>-<variable>
<Name>SCREW_RPM_SET</Name>
<Value>550</Value>
</variable>-<variable>
<Name>SCREW_RPM_REAL</Name>
<Value>550.085388183594</Value>
</variable>-<variable>
<Name>TORQUE</Name>
<Value>1.21340000629425</Value>
</variable>-<variable>
<Name>CURRENT</Name>
<Value>60.1959991455078</Value>
</variable>-<variable>
<Name>KW_KG</Name>
<Value>0</Value>
</variable>-<variable>
<Name>KW</Name>
<Value>-0.990000009536743</Value>
</variable>-<variable>
<Name>MELT_PRESSURE</Name>
<Value>0</Value>
</variable>-<variable>
<Name>MELT_TEMPERATURE</Name>
<Value>214</Value>
</variable>-<variable>
<Name>PV1</Name>
<Value>216</Value>
</variable>-<variable>
<Name>SP1</Name>
<Value>210</Value>
</variable>-<variable>
<Name>PV2</Name>
<Value>239</Value>
</variable>-<variable>
<Name>SP2</Name>
<Value>220</Value>
</variable>-<variable>
<Name>PV3</Name>
<Value>220</Value>
</variable>-<variable>
<Name>SP3</Name>
<Value>220</Value>
</variable>-<variable>
<Name>PV4</Name>
<Value>220</Value>
</variable>-<variable>
<Name>SP4</Name>
<Value>220</Value>
</variable>-<variable>
<Name>PV5</Name>
<Value>209</Value>
</variable>-<variable>
<Name>SP5</Name>
<Value>210</Value>
</variable>-<variable>
<Name>PV6</Name>
<Value>210</Value>
</variable>-<variable>
<Name>SP6</Name>
<Value>210</Value>
</variable>-<variable>
<Name>PV7</Name>
<Value>210</Value>
</variable>-<variable>
<Name>SP7</Name>
<Value>210</Value>
</variable>-<variable>
<Name>PV8</Name>
<Value>210</Value>
</variable>-<variable>
<Name>SP8</Name>
<Value>210</Value>
</variable>-<variable>
<Name>PV9</Name>
<Value>210</Value>
</variable>-<variable>
<Name>SP9</Name>
<Value>210</Value>
</variable>-<variable>
<Name>PV10</Name>
<Value>210</Value>
</variable>-<variable>
<Name>SP10</Name>
<Value>210</Value>
</variable>-<variable>
<Name>PV11</Name>
<Value>220</Value>
</variable>-<variable>
<Name>SP11</Name>
<Value>220</Value>
</variable>
</CollectedData>
</recordedData>
Can anyone provide a sample sql script for extracting all the data from it please.
i would really apreciate this since im new to xml.
Thanks in advance.
If you have your data in a table already, you can use something like this:
DECLARE #Tmp TABLE (ID INT NOT NULL, XmlContent XML)
INSERT INTO #TMP VALUES(1, '......(your entire XML here).......)
SELECT
ID,
MACHINE = XmlContent.value('(/recordedData/machine)[1]', 'varchar(50)'),
RecordingDate = XmlContent.value('(/recordedData/date)[1]', 'varchar(50)'),
RecordingTime = XmlContent.value('(/recordedData/hour)[1]', 'varchar(50)'),
VariableName = XVar.value('(Name)[1]', 'varchar(50)'),
VariableValue = XVar.value('(Value)[1]', 'varchar(50)')
FROM
#Tmp
CROSS APPLY
XmlContent.nodes('/recordedData/CollectedData/variable') AS XTbl(XVar)
This gives you an output something like:
.... and so on - listing all the variables with their name and value.
I have a table in SQL Server 2008 that it has some columns. One of these columns is in Xml format
and I want to update some attributes.
For example my Xml column's name is XmlText and it's value in 5 first rows is such as:
<Identification Name="John" Family="Brown" Age="30" />
<Identification Name="Smith" Family="Johnson" Age="35" />
<Identification Name="Jessy" Family="Albert" Age="60" />
<Identification Name="Mike" Family="Brown" Age="23" />
<Identification Name="Sarah" Family="Johnson" Age="30" />
and I want to change all Age attributes that are 30 to 40 such as below:
<Identification Name="John" Family="Brown" Age="40" />
<Identification Name="Smith" Family="Johnson" Age="35" />
<Identification Name="Jessy" Family="Albert" Age="60" />
<Identification Name="Mike" Family="Brown" Age="23" />
<Identification Name="Sarah" Family="Johnson" Age="40" />
From the early versions of your question it looks like your XML actually is on different rows in a table. If that is the case you can use this.
update YourTable set
XMLText.modify('replace value of (/Identification/#Age)[1] with "40"')
where XMLText.value('(/Identification/#Age)[1]', 'int') = 30
Working sample using a table variable.
declare #T table(XMLText xml)
insert into #T values('<Identification Name="John" Family="Brown" Age="30" />')
insert into #T values('<Identification Name="Smith" Family="Johnson" Age="35" />')
insert into #T values('<Identification Name="Jessy" Family="Albert" Age="60" />')
insert into #T values('<Identification Name="Mike" Family="Brown" Age="23" />')
insert into #T values('<Identification Name="Sarah" Family="Johnson" Age="30" />')
update #T set
XMLText.modify('replace value of (/Identification/#Age)[1] with "40"')
where XMLText.value('(/Identification/#Age)[1]', 'int') = 30
select *
from #T
Try this:
declare #xml XML
SET #xml = '<Root>
<Identification Name="John" Family="Brown" Age="30" />
<Identification Name="Smith" Family="Johnson" Age="35" />
<Identification Name="Jessy" Family="Albert" Age="60" />
<Identification Name="Mike" Family="Brown" Age="23" />
<Identification Name="Sarah" Family="Johnson" Age="30" />
</Root>'
DECLARE #nodeCount int
DECLARE #i int
SET #i = 1
SELECT #nodeCount = #xml.value('count(/Root/Identification/#Age)','int')
PRINT 'Number of nodes found: ' + STR(#nodeCount)
WHILE (#i <= #nodeCount)
BEGIN
Set #xml.modify('replace value of (/Root/Identification/#Age)[.=30][1] with "40"')
SET #i = #i + 1
END
SELECT #xml
The modify method is your response. But if you need to have a condition you can use if expression in with section of this method.
DECLARE #t TABLE (RecordXML XML);
Declare #xml XML
SET #xml = '<Root>
<Identification Name="John" Family="Brown" Age="30" />
<Identification Name="Smith" Family="Johnson" Age="35" />
<Identification Name="Jessy" Family="Albert" Age="60" />
<Identification Name="Mike" Family="Brown" Age="23" />
<Identification Name="Sarah" Family="Johnson" Age="30" />
</Root>'
INSERT #t VALUES (#xml);
Declare #value nvarchar(50)
DECLARE #oldvalue nvarchar(50)
SET #value = '40'
SET #oldvalue = '30'
Declare #update_count xml
select #update_count = #xml.query('count(/Root/Identification/#Age[.=sql:variable("#oldvalue")])')
Declare #number int
select #number = convert(int, (convert(nvarchar(50), #update_count)))
declare #Node int
set #Node = 1
while #Node <= #number
begin
UPDATE
#t
SET
RecordXML.modify('replace value of
(/Root/Identification/#Age[.=sql:variable("#oldvalue")])[1] with sql:variable("#value")')
WHERE
RecordXML.exist('/Root/Identification[#Age=sql:variable("#oldvalue")]') = 1;
set #Node = #Node + 1
end
SELECT * FROM #t;