Create single node if select single node is null - c#

I have a program that updates a config file. For example, the config file may contain:
<configuration>
<userSettings>
<setting name="phoneNumber" serializeAs="String">
<value>123-456-7890</value>
</setting>
</userSettings>
</configuration>
To update this config file, I use the following:
XmlNode phoneNumberNode = theConfig.SelectSingleNode("configuration/userSettings/setting[#name='phoneNumber']");
phoneNumberNode.FirstChild.InnerText = this._cloudPublisherWebURL;
Now, during the update I want to update phoneNumber and address. Address may or may not be in the config file.
If SelectSingleNode is null, I would like to create a node with the given path and set its value.
XmlNode addressNode = theConfig.SelectSingleNode("configuration/userSettings/setting[#name='address']");
if(addressNode == null)
{
//..Create the node here
}
How can I create the node with value at the given path?

XmlNode addressNode = theConfig.SelectSingleNode("configuration/userSettings");
XmlNode setting = addressNode.Item(0).SelectSingleNode("configuration/userSettings/setting[#name='phoneNumber']");
setting.SetAttribute("name", "address"); //this is to change the name attribute value into address

Related

If name attribute is X then get content of value attribute

I am struggling with code in C# for getting value depending on the first argument from XML:
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<TestRunParameters>
<Parameter name="browser" value="chrome" />
<Parameter name="browserVersion" value="101.0"/>
<Parameter name="os" value="WIN11"/>
<Parameter name="build" value=""/>
</TestRunParameters>
</RunSettings>
I would like to check if the parameter name is browser then take its content from value.
I am able to get this values by SelectNodes("//#value") and node[0].Value but I am wondering if there is another way of getting those values without specifing the position. Here is my code:
var filename = #"../../../browser.runsettings";
var xmlDoc = new XmlDocument();
xmlDoc.Load(filename);
XmlNodeList node = xmlDoc.SelectNodes("//#value");
var browserValue = node[0].Value;
Thanks in advance for help
I think you should cycle thought them and check if the name is Browser and then use the value. Something like this should do it
foreach (XmlNode node in nodes)
{
if (node.Name != "Browser") continue;
browserValue = node.Value;
break;
}
You can also get single node by using .SelectSingleNode() instead of using .SelectNodes()
var filename = #"../../../browser.runsettings";
var xmlDoc = new XmlDocument();
xmlDoc.Load(filename);
XmlNode node = xmlDoc.SelectSingleNode("//#value");
var browserValue = node.Value;

C# Write XML File Containing Unknown Number of Nodes With the Same Name

Using C#, I'm trying to write an XML file that will contain an unknown number (unknown at compile time, I can figure out the number after I search the SQLite DB) of nodes (data being read from an SQLite DB) that will be named the same (Setting). The number of Setting nodes potentially can be in the thousands.
<Set>
<Setting Name="Ted" empID="60000004">Ted</Setting>
<Setting Name="Bill" empID="60000007">Bill</Setting>
<Setting Name="Steve empID="60000010">Steve</Setting>
<Setting Name="Sara" empID="60000013">Sara</Setting>
<Setting Name="Tom" empID="60000016">Tom</Setting>
<Setting Name="Sam" empID="60000019">Sam</Setting>
<Setting Name="Alex" empID="60000022">Alex</Setting>
<Setting Name="Sue" empID="60000025">Sue</Setting>
<Setting Name="Jill" empID="60000028">Jill</Setting>
<Setting Name="Mya" empID="60000031">Mya</Setting>
</Set>
Here is my code that I'm using, but failing:
XDocument doc = new XDocument(new XElement("Set"));
while (reader.Read())
{
doc.Element("Set").Add(new XElement("Setting", _Name));
doc.Element("Set").Element("Setting").Add(new XAttribute("empID", _ID));
}
doc.Save(_sOutputFolderName + "Employee_Information.xml");
You're attempting to add the XAttribute to the same XElement on each loop. Should be something like:
XDocument doc = new XDocument(new XElement("Set"));
for (int i = 0; i < 10; i++)
{
var _Name = "n" + i ;
var _ID = "12" + i;
var setting = new XElement("Setting", _Name );
setting.Add(new XAttribute("empID", _ID));
doc.Element("Set").Add(setting);
}
Console.WriteLine(doc.ToString());
Try this...
XDocument doc = new XDocument(new XElement("Set"));
while (reader.Read()) {
var setting = new XElement("Setting", "the name");
setting.Add(new XAttribute("empID", "the id"));
doc.Root.Add(setting);
}

Get value in xml from c#

This question must be easy, but I faced a problem,
which I can't deal with.
No matter what I try I am unable to parse this xml with linq and get the xml value.
The error is "System.Collections.Generic.IEnumerable' does not contain a definition for 'Element' and no extension method 'Element' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?)"
I want to find the Xelement attribute.value which children have a concrete attribute.value.
How can I get the attribute.value?
thanks
xml
<submitInfo>
<setting name="file1" file ="example3.c" info ="open it!" serializeAs="String">
<add name="file11" program="example2.c" />
<add name="file12" value="example1.c" />
<value />
<setting name="file2" file ="example23.c" info ="open it!" serializeAs="String">
<add name="file21" program="example22.c" />
<add name="file22" value="example21.c" />
<value />
</setting>
</submitInfo>
code:
var title1 = from q in doc.Element("content").Element("submitInfo").Elements("setting")
select q;
foreach (var t1 in title1)
{
Console.WriteLine(
String.Format(
name = title1.Element("name").Value,
file= title1.Element("file").Value,
info= title1.Attribute("info").Value));
}
//get setting info
var title = from p in doc.Element("content").Element("submitInfo").Element("setting").Elements("add")
select p;
foreach (var t1 in title)
{
Console.WriteLine(
String.Format(
name = title1.Element("name").Value,
value = title1.Element("program").Value));
This is one problem:
name = title1.Element("name").Value,
file= title1.Element("file").Value,
info= title1.Attribute("info").Value));
Look at your XML:
<setting name="file1" file ="example3.c" info ="open it!" serializeAs="String">
<add name="file11" program="example2.c" />
<add name="file12" value="example1.c" />
<value />
</setting>
It doesn't have a name or file element - those are attributes. So you want something like:
string name = t1.Attribute("name");
string file = t1.Attribute("file");
string info = t1.Attribute("info");
Note that this is using t1, not title1 - otherwise you're asking for the data from the query, rather than for the specific element of the query.
Additionally, you really don't need a query expression here. Just use:
var title1 = doc.Element("content").Element("submitInfo").Elements("setting");
Another problem is that you're currently calling string.Format with three assignments inside. I suspect you actually wanted:
Console.WriteLine("{0} {1} {2}", t1.Attribute("name"),
t1.Attribute("file"), t1.Attribute("info"));

How to check XMLNode is exist or not in Windows Phone

I am writing Windows Phone 8 application, and I am getting XML data from web service,in some response, in my XML document I am getting some "Tags" and in other response I do not getting those tags, so how do I check that XNode is exist or not?
See my XML document below:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Group>
<Id>205647</Id>
<Name>Docs</Name>
</Group>
<Group>
<Id>205648</Id>
<Name>Photos</Name>
</Group>
</root>
Now, in above document, the Descendant "GROUP" is exist in some results and doesn't exist in other results,How do I check that?
Create an extension method like this :
public static string TryGetElementValue(this XElement parentEl, string elementName, string defaultValue = null)
{
var foundEl = parentEl.Element(elementName);
if(foundEl != null)
{
return foundEl.Value;
}
else
{
return defaultValue;
}
}
This approach allows you to keep a clean code with isolating the check of element presence. It also allow you to define a default value, which can be helpful
You could go through all nodes with the XmlTextReader and look for a specific XmlNode Name.
http://www.w3schools.com/xpath/xpath_syntax.asp
Try this snippet with your xml:
XmlDocument doc = new XmlDocument();
doc.Load("your.xml");
//Select the book node with the matching attribute value.
XmlNode nodeToFind;
XmlElement root = doc.DocumentElement;
// Selects all the title elements that have an attribute named group
nodeToFind = root.SelectSingleNode("//title[#group]");
if( nodeToFind != null )
{
// It was found, manipulate it.
}
else
{
// It was not found.
}
Have a look at this too. updating an existing xml file in Windows Phone
Hope it helps!

Read value from XML ignoring any namespaces

I have an XML file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="publisher" type="KP.Common.Util.XamlConfigurationSection, KP.Common"/>
</configSections>
<publisher>
<p:Publisher xmlns:p="http://schemas.KP.com/xaml/common/notification">
<p:KPLogSubscriber MinimumImportance="Information" />
<p:EventLogSubscriber MinimumImportance="Warning" Source="KPTTY" Log="Application" />
<p:DatabaseMailSubscriber xmlns="http://schemas.KP.com/xaml/data/ef" MinimumImportance="Error" ProfileName = "" Recipients = "administrator#firm.com" Subject = "KPTTY Error" />
</p:Publisher>
</publisher>
</configuration>
I am trying to read the value of the key Recipients using this code:
XmlDocument config = new XmlDocument();
config.Load(configPath);
XmlNode node = config.SelectSingleNode(#"/*[local-name() = 'configuration']/*[local-name() = 'publisher']/*[local-name() = 'Publisher']/*[local-name() = 'DatabaseMailSubscriber']/#Recipients");
Console.WriteLine(node.Value);
but I get an exception (node is null). Is there something wrong with my Xpath? I am trying to ignore any namespaces that might not be present in the xml.
If it is OK to use Linq2Xml
XDocument xDoc = XDocument.Load(fname);
var recipients = xDoc.Descendants()
.First(d => d.Name.LocalName == "DatabaseMailSubscriber")
.Attribute("Recipients")
.Value;
You forgot to do local-name for "Recipients". "Recipients" attribute have empty prefix meaning its namespace is xmlns="http://schemas.KP.com/xaml/data/ef" as defined on the "DatabaseMailSubscriber" element.
I.e. if you don't care of path you can simple use "//" for "any child:
"//*[local-name() = 'DatabaseMailSubscriber']/#*[local-name() = 'Recipients]"
Note: consider actually using namespace properly... or use XDocument as suggested by L.B.

Categories

Resources