How to C# Reading xml file - c#

I have an XML file. I want C # with the desktop application. There are similar solutions on the site. But I can't read with the XML I have. How should I proceed about this?
<?xml version="1.0"?>
<RealTimeMetrics SiteId="Site ID">
<Properties>
<Version>3</Version>
<TransmitTime>1581582053</TransmitTime>
<MacAddress>00:b0:9d:23:72:f0</MacAddress>
<IpAddress>192.168.1.99</IpAddress>
<HostName>Cam-19100400</HostName>
<HttpPort>80</HttpPort>
<HttpsPort>443</HttpsPort>
<Timezone>3</Timezone>
<TimezoneName>(GMT 03:00) Nairobi</TimezoneName>
<DST>0</DST>
<HwPlatform>2500</HwPlatform>
<SerialNumber>19100400</SerialNumber>
<DeviceType>0</DeviceType>
<SwRelease>4.1.4005.2249</SwRelease>
</Properties>
<RTReport Date="2020-02-13T11:20:53">
<RTObject Id="0" DeviceId="Demo" Devicename="Demo" ObjectType="0" Name="TEST">
<RTCount TotalEnters="0" TotalExits="0"/>
</RTObject>
</RTReport>
</RealTimeMetrics>

I used simple solution to read and edit XML file:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("path\to\file.xml");
XmlNode node = xmlDoc.SelectSingleNode("//nodeName");
node.InnerText = value;
xmlDoc.Save("path\to\file.xml");
You can load this file, read single node or all nodes, change value of InnerText or Add Atributes, end save this file

Related

C# Skip anything to next tag

I have a log file in xml format like
<log> // skip this node
<?xml version="1.0" encoding="UTF-8"?>
<qbean logger="main-logger">
</qbean>
</log>
<log> // go to this node
</log>
Now ReadToNextSibling("log") throw an exception an I need to skip content of first "log" tag and move to next "log" tag without throwing exception.
Is there a way?
Hint:
Your XML is invalid since the <?xml version="1.0" encoding="UTF-8"?> has to be before the root element. You can search for it and remove it if that fixes your problem. You can use yourXml.Repalce("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "")
You have to create a root element for your XML to be valid for parsing.
Then, you can use the XmlDocument class to parse the XML data that you have and skip anything you want. You would need something like this:
var document = new XmlDocument();
document.LoadXml(yourXml);
document.DocumentElement.ChildNodes[1]

why XElement cannot save my xml file to the file?

I want to construct a long xml string and some of its entities are from another xml file read by a dll. In the end, I'd like to save this xml string to a file by XElement.Save(). It cannot save the string to the file.
For example:
XElement root = new XElement("Root");
// .....
root.Save(filename); // <-- wrong!
However, If I do not use the dll, everything is fine. Even I just call the dll and do nothing else, it won't work for me. Can anybody help me? Thanks
For Appending Node into existing XML File:
From beginning,
1) Create one Root.xml file:
<?xml version="1.0" encoding="utf-8"?>
<Main>
</Main>
2) Use this code to Load and Append Nodes:
XElement xml = new XElement("Root");
XDocument xdoc = XDocument.Load("Root.xml");
xdoc.Element("Main").Nodes().Last().AddAfterSelf(xml); //append after the last backup element
xdoc.Save("Root.xml");

how Deserializing this type of xml file?

<row>
<id>1</id>
<code></code>
<name></name>
<address></address>
<state></state>
<zone>?</zone>
</row>
<row>
<id>2</id>
<code>AA</code>
<name>Ataria</name>
<address>Sitapur National Highway 24, Uttar Pradesh</address>
<state>Uttar Pradesh</state>
<zone>NER</zone>
</row>
i have no root element in this xml file only row element start and end this xml file.
how Deserializing this type of data ? in c#
If you sure that missing root is only the one issue with your XML - just add it manually:
string fileContent = File.ReadAllText(path);
string rawXml = "<root>" + fileContent + "</root>";
// now you can use LINQ-to-XML or whatever
XDocument xdoc = XDocument.Load(rawXml);
You can also load an XML Fragment directly, via
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create("tracelog.xml", settings))
{
while (reader.Read())
{
// Process each node of the fragment,
// possibly using reader.ReadSubtree()
}
}
You would create XElements by passing the results of reader.ReadSubTree() to XElement.Load(...).
Well to start with, it's not an XML file - or at least, it doesn't represent an XML document.
One option would be to copy the file into a new file which does have document start/end tags... then you can load it as a normal document. Just create a file, write a document start tag, copy the contents of this file, then write a document end tag, and close the file handle. You could even do this in memory.
Alternatively, it may be possible to read it as it is, in fragments - possibly via XmlReader. I can't say it's something I've done, and I'd generally encourage you to create a full XML file instead, as then you'll be on more familiar territory.
its not an XML file if it doesn't have the root. parser will throw an error if you try to parse it. you can do this way
<?xml version="1.0"?>
<Root>
--- add your file content here
</Root>
then give this file path to the parser.

Editing an XML file?

How do I add another element/childnode to a specific parent node in an XML file?
Specifically a new video object to the media node.
I want to turn this:
<?xml version="1.0" encoding="utf-8" ?>
<media>
<Video name="Gladiator">
<English>path1</English>
<Chinese>path2</Cinese>
<French>path3</French>
</Video>
<Video name="Transformers">
<English>path4</English>
<Chinese>path5</Cinese>
<French>path6</French>
</Video>
</media>
into this:
<?xml version="1.0" encoding="utf-8" ?>
<media>
<Video name="Gladiator">
<English>path1</English>
<Chinese>path2</Cinese>
<French>path3</French>
</Video>
<Video name="Transformers">
<English>path4</English>
<Chinese>path5</Cinese>
<French>path6</French>
</Video>
<Video name="Terminator">
<English>path7</English>
<Chinese>path8</Cinese>
<French>path9</French>
</Video>
</media>
If I open an xmlTextwriter, create a new element tag, add attributes and end the element tag; it deletes all previous data in the text file :/
If you use the class XmlTextWriter, you need to read your xml file to get the content before using XmlTextWriter. XmlTextWriter does not load the content of your xml file. That's why all your previous data are gone.
XmlDocument is the simplest way to add a new node.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filePath);
XmlNode node = FindYourNode(xmlDoc); //Method to find the specific node
node.AppendChild(yourNewXmlNode);
xmlDoc.Save(filePath);
If your xml file is small, the class XmlDocument is perfectly fine. But if you have to manipulate a big xml file, I would suggest to use another class because XmlDocument can hurt your performance.
In that case, I would use a combination of XmlReader and XmlWriter.
I would do something along these lines:
mediaElement.AppendChild(xmlDocument.CreateElement("Video"))
Where mediaElement is a reference to the <media/> element and xmlDocument is of the type XmlDocument.

C# XmlDocument Nodes

I'm trying to access UPS tracking info and, as per their example, I need to build a request like so:
<?xml version="1.0" ?>
<AccessRequest xml:lang='en-US'>
<AccessLicenseNumber>YOURACCESSLICENSENUMBER</AccessLicenseNumber>
<UserId>YOURUSERID</UserId>
<Password>YOURPASSWORD</Password>
</AccessRequest>
<?xml version="1.0" ?>
<TrackRequest>
<Request>
<TransactionReference>
<CustomerContext>guidlikesubstance</CustomerContext>
</TransactionReference>
<RequestAction>Track</RequestAction>
</Request>
<TrackingNumber>1Z9999999999999999</TrackingNumber>
</TrackRequest>
I'm having a problem creating this with 1 XmlDocument in C#. When I try to add the second:
<?xml version="1.0" ?> or the <TrackRequest>
it throws an error:
System.InvalidOperationException: This
document already has a
'DocumentElement' node.
I'm guessing this is because a standard XmlDocument would only have 1 root node. Any ideas?
Heres my code so far:
XmlDocument xmlDoc = new XmlDocument();
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
XmlElement rootNode = xmlDoc.CreateElement("AccessRequest");
rootNode.SetAttribute("xml:lang", "en-US");
xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
xmlDoc.AppendChild(rootNode);
XmlElement licenseNode = xmlDoc.CreateElement("AccessLicenseNumber");
XmlElement userIDNode = xmlDoc.CreateElement("UserId");
XmlElement passwordNode = xmlDoc.CreateElement("Password");
XmlText licenseText = xmlDoc.CreateTextNode("mylicense");
XmlText userIDText = xmlDoc.CreateTextNode("myusername");
XmlText passwordText = xmlDoc.CreateTextNode("mypassword");
rootNode.AppendChild(licenseNode);
rootNode.AppendChild(userIDNode);
rootNode.AppendChild(passwordNode);
licenseNode.AppendChild(licenseText);
userIDNode.AppendChild(userIDText);
passwordNode.AppendChild(passwordText);
XmlElement rootNode2 = xmlDoc.CreateElement("TrackRequest");
xmlDoc.AppendChild(rootNode2);
An XML document can only ever have one root node. Otherwise it's not well formed. You will need to create 2 xml documents and join them together if you need to send both at once.
Its throwing an exception because you are trying to create invalid xml. XmlDocument will only generate well formed xml.
You could do it using an XMLWriter and setting XmlWriterSettings.ConformanceLevel to Fragment or you could create two XmlDocuments and write them out into the same stream.
Build two separate XML documents and concatenate their string representation.
It looks like your node structure always be the same. (I don't see any conditional logic.) If the structure is constant you could define an XML template string. Load that string into an XML Document & do a SelectNode to populate individual nodes.
That may be simpler/cleaner than programatically creating the root, elements & nodes.

Categories