Change an XML node value - c#

I have an xml document that looks like this
<?xml version="1.0"?>
<XML>
<VIDEO>
<WIDTH>800</WIDTH>
<HEIGHT>600</HEIGHT>
<COLORBITS>32</COLORBITS>
<GAMMA>255</GAMMA>
<FULLSCREEN>TRUE</FULLSCREEN>
<REFLECTION>true</REFLECTION>
<LIGHTMAP>true</LIGHTMAP>
<DYNAMICLIGHT>true</DYNAMICLIGHT>
<SHADER>true</SHADER>
<CHARACTORTEXTURELEVEL>0</CHARACTORTEXTURELEVEL>
<MAPTEXTURELEVEL>0</MAPTEXTURELEVEL>
<EFFECTLEVEL>0</EFFECTLEVEL>
<TEXTUREFORMAT>1</TEXTUREFORMAT>
<NHARDWARETNL>false</NHARDWARETNL>
</VIDEO>
</XML>
I want to change the value of the "MAPTEXTURELEVEL" node from 0 to 6 using the checked statement of a checkbox in a C# application, but I really have no idea of how I can do it.

I don't have VS to test it, but it should be something like this using LINQ to XML:
var doc = XDocument.Load("video.xml");
doc
.Element("XML")
.Element("VIDEO")
.SetElementValue("MAPTEXTURELEVEL", 6);
doc.Save("video_modified.xml");
Hope it helps!

Related

How to parse a XML with nested XML text

Trying to read XML file with nested XML object with own XML declaration. As expected got exception:
Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.
How can i read that specific element as text and parse it as separate XML document for later deserialization?
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Items>
<Item>
<Target type="System.String">Some target</Target>
<Content type="System.String"><?xml version="1.0" encoding="utf-8"?><Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data></Content>
</Item>
</Items>
</Data>
Every approach i'm trying fail due to declaration exception.
var xml = System.IO.File.ReadAllText("Info.xml");
var xDoc = XDocument.Parse(xml); // Exception
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml); // Exception
var xmlReader = XmlReader.Create(new StringReader(xml));
xmlReader.ReadToFollowing("Content"); // Exception
I have no control over XML creation.
The only way I would know is by getting rid of the illegal second <?xml> declaration. I wrote a sample that will simply look for and discard the second <?xml>. After that the string has become valid XML and can be parsed. You may need to tweak it a bit to make it work for your exact scenario.
Code:
using System;
using System.Xml;
public class Program
{
public static void Main()
{
var badXML = #"<?xml version=""1.0"" encoding=""UTF-8""?>
<Data>
<Items>
<Item>
<Target type=""System.String"">Some target</Target>
<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?><Data><Items><Item><surname type=""System.String"">Some Surname</surname><name type=""System.String"">Some Name</name></Item></Items></Data></Content>
</Item>
</Items>
</Data>";
var goodXML = badXML.Replace(#"<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?>"
, #"<Content type=""System.String"">");
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(goodXML);
XmlNodeList itemRefList = xmlDoc.GetElementsByTagName("Content");
foreach (XmlNode xn in itemRefList)
{
Console.WriteLine(xn.InnerXml);
}
}
}
Output:
<Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data>
Working DotNetFiddle: https://dotnetfiddle.net/ShmZCy
Perhaps needless to say: all of this would not have been needed if the thing that created this invalid XML would have applied the common rule to wrap the nested XML in a <![CDATA[ .... ]]> block.
The <?xml ...?> processing declaration is only valid on the first line of an XML document, and so the XML that you've been given isn't well-formed XML. This will make it quite difficult to parse as is without either changing the source document (and you've indicated that's not possible) or preprocessing the source.
You could try:
Stripping out the <?xml ?> instruction with regex or string manipulation, but the cure there may be worse than the disease.
The HTMLAgilityPack, which implements a more forgiving parser, may work with an XML document
Other than that, the producer of the document should look to produce well-formed XML:
CDATA sections can help this, but be aware that CDATA can't contain the ]]> end tag.
XML escaping the XML text can work fine; that is, use the standard routines to turn < into < and so forth.
XML namespaces can also help here, but they can be daunting in the beginning.

find if a code exists in xml, using c#

I am starting to work with xml and I am trying to know if there is a way to search a code in this.
Here you are my xml
<?xml version="1.0" encoding="UTF-8"?>
<doctors_hospital>
<doctor>
<code>1757D</code>
<name>one</name>
</doctor>
<doctor>
<code>1169L</code>
<name>two</name>
</doctor>
... continues xml
</doctors_hospital>
I want to look for the code "aab" using c#, and this is my code..
var document =new XmlDocument();
document.Load("O:\\test\\doctor.xml");
XmlNode doctor;
XmlNode root = document.DocumentElement;
doctor = root.SelectSingleNode("/doctors_hospital/doctor/code='aab'");
I can not do this. any suggestion? thanks
Assuming SelectingSingleNode takes a standard XPath expression, what you want to use is
/doctors_hospital/doctor[code='aab']
This will select the entire doctor node with the matching code value.
I agree with Jim, alternatively you could also use Linq to Xml and do this.
XDocument doc = XDocument.Load(filepath);
var codeExist = doc.Descendants("code").Any(x=>(string)x.Value == "1169L");
Check this Demo

Linq2Xml Remove specific attribute name and their values

I have this XML, and i am trying to delete those:
Name="items"
Name="shipmentsShipmentIndex"
"Name" is not going to change,
The word that will be change is the word between the quotation marks, in this example:
items and shipmentsShipmentIndex
<?xml version="1.0" encoding="UTF-8"?>
<RootDTO xmlns:json='http://james.newtonking.com/projects/json'>
<destination>
<name>XXX</name>
</destination>
<orderData>
<items json:Array='true'>
<shipmentIndex Name="items">0</shipmentIndex>
</items>
<items json:Array='true'>
<shipmentIndex Name="items">0</shipmentIndex>
</items>
<shipments json:Array='true'>
<shipmentIndex Name="shipmentsShipmentIndex">0</shipmentIndex>
</shipments>
</orderData>
</RootDTO>
How can i find all these occurrences and remove them(or replace them with nothing)?
I tried a bunch of variations like: Name{1}[a-zA-Z]+"\b
You wrote this is ASP.NET. You can use Linq2Xml to perform this operation very quickly (LinqPad example):
void Main()
{
var test = XDocument.Parse("<root><node name=\"name value\">Text</node></root>");
foreach(var attr in test.Descendants().SelectMany(el=>el.Attributes("name")))
attr.Remove();
test.Dump();
}
So from this:
<root>
<node name="name value">Text</node>
</root>
You get this:
<root>
<node>Text</node>
</root>
The snippet will remove ALL name attributes from every single element in the XML aside of the root one. If you want to do something else (like just empty the attribute, or include the root element), let me know.
Don't parse XML with regular expressions. Use an XML aware tool.
For example, in xsh, you can achieve this with
open file.xml ;
rm //#Name ;
save :b ;
Try this RegEx:
Name=\"(.*?)\"

Process namespaces using XmlReader

I have a complex XML file with structure as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="xxx:xxx:xxx:xxx:xxxxx:xxx:xsd:xxxx.xxx.xxx.xx">
<Element1>
<Element2>
<Element2A>xxxxxx</Element2A>
<Element2B>2012-08-29T00:00:00</Element2B>
</Element2>
</Element1>
</Document>
Now I am using XmlReader to read this XML document and process information as follows
XmlReader xr = XmlReader.Create(filename);
while (xr.Read())
{
xr.MoveToElement();
XElement node = (XElement)XElement.ReadFrom(xr);
Console.WriteLine(node.Name);
}
xr.Close();
The problem I am facing is in the output the namespace is prefixed to the ElementName. E.g output
{xxx:xxx:xxx:xxx:xxxxx:xxx:xsd:xxxx.xxx.xxx.xx}Element1
Is there any way I can remove/ handle this as I need to do further filtering using Element names and Child names.
XElement.Name is not (as you might expect) a String, but rather an XName which has a LocalName property, thus:
Console.WriteLine(node.Name.LocalName);
You may want to remove the namespace. One way to remove namespace is to write c# code and other way is to use XSLT transformation as suggested in Remove Namespace
-Milind

Parse three specific elements from an XML snippet in C# 2.0

How could parse the value of few tag from my XML using C# 2.0?
I want to parse the tag and their value like
1) <v9:Severity>SUCCESS</v9:Severity>
2) <v9:TrackingNumber>634649515000016</v9:TrackingNumber>
3) <v9:Image>iVBORw0KGgoAAAANSUhEUgAAAyAAAASwAQAAAAAryhMIAAAagEl</v9:Image>
How to get the value of those above elements programmatically with C# 2.0?
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<soapenv:Body>
<v9:ProcessShipmentReply xmlns:v9="http://fedex.com/ws/ship/v9">
<v9:HighestSeverity xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SUCCESS</v9:HighestSeverity>
<v9:Notifications xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v9:Severity>SUCCESS</v9:Severity>
<v9:Source>ship</v9:Source>
<v9:Code>0000</v9:Code>
<v9:Message>Success</v9:Message>
<v9:LocalizedMessage>Success</v9:LocalizedMessage>
</v9:Notifications>
<v9:CompletedShipmentDetail>
<v9:CompletedPackageDetails xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v9:SequenceNumber>1</v9:SequenceNumber>
<v9:TrackingIds>
<v9:TrackingIdType>GROUND</v9:TrackingIdType>
<v9:TrackingNumber>634649515000016</v9:TrackingNumber>
</v9:TrackingIds>
<v9:Barcodes>
<v9:BinaryBarcodes>
<v9:Type>COMMON_2D</v9:Type>
<v9:Value>Wyk+HjAxHTAyMDI3ODAdODQwHTEzNx02MzQ2NDk1</v9:Value>
</v9:BinaryBarcodes>
<v9:StringBarcodes>
<v9:Type>GROUND</v9:Type>
<v9:Value>9612137634649515000016</v9:Value>
</v9:StringBarcodes>
</v9:Barcodes>
<v9:Label>
<v9:Type>OUTBOUND_LABEL</v9:Type>
<v9:ShippingDocumentDisposition>RETURNED</v9:ShippingDocumentDisposition>
<v9:Resolution>200</v9:Resolution>
<v9:CopiesToPrint>1</v9:CopiesToPrint>
<v9:Parts>
<v9:DocumentPartSequenceNumber>1</v9:DocumentPartSequenceNumber>
<v9:Image>iVBORw0KGgoAAAANSUhEUgAAAyAAAASwAQAAAAAryhMIAAAagEl</v9:Image>
</v9:Parts>
</v9:Label>
</v9:CompletedPackageDetails>
</v9:CompletedShipmentDetail>
</v9:ProcessShipmentReply>
</soapenv:Body>
</soapenv:Envelope>
Since you said that you use c# 2.0 (and, thus, cannot use LINQ-to-XML), the easiest way to just find single values out of your XML would be to use XPath:
You can use an XPathNavigator (MSDN: Select XML Data using XPathNavigator)
or you can use XmlNode.SelectNodes directly.
Since your XML contains namespaces <v9:...>, the issue gets a bit more complicated: You need to initialize an XmlNamespaceManager and pass it to the XPathNavigator. Here is a blog post that explains this issue in detail; an example can also be found at the XmlNode.SelectNodes MSDN page (see link above).
Query XML with Namespaces using XPathNavigator

Categories