c# LINQ how to determin a XElement with specific attribute - c#

i would like to realize this functionality:
determin, whether the XML file has a XElement with specific attribute or not.
This is the example XML code:
<root>
<pou objectId="name">
</pou>
<pou objectId="value">
</pou>
<pou objectId="address">
</pou>
</root>
I would like to determin, whether the XML file has a specific XElement "pou" with attribute ObjectId "name" or not.
The following is my code in C# using Descendants
XDocument xdoc = XDocument.Load(#"C:\Users\jsc\Desktop\TestForInherit.xml");
XDocument xNew = new XDocument();
xNew.Add(new XElement("root"));
if (xdoc.Descendants("pou").Where(x=> (string)x.Attribute("objectId") =="name").Any()==true)
{
xNew.Add(new XElement("pou", new XAttribute("objectId", "name")));
}
xNew.Save(#"C:\Users\jsc\Desktop\TestForInheritNew.xml");
If the xml file has the XElement with specific attribute value, then add thie XElement to the new XML file.
But unfortunatelly it does not work. Can anyone give me some advise.

Please try the following syntax to check if there's an attribute with specific name:
xdoc.Descendants("pou").Where(x=> x.Attribute("objectId") != null)

Related

How to read a node in a serialized XML file?

I'm trying to read a node in a serialized XML file. Here is the the first part of the XML file (I'm using a screen cap because pasting ended up with weird formatting):
And this is the code I'm using to read the XML and the error it's throwing:
I'm trying to read the <ScenarioDescription> node.
As per request, here's the entire XML file. Unfortunately it's just a complete mess. Here is a link to the XML file.
You should You would need to specify the namespace. In this particular case, the default namespace is used to declare the http://schemas.datacontract.org/2004/07/ModelLib namespace.
var xml = new XmlDocument();
xml.LoadXml(str);
XmlNamespaceManager ns = new XmlNamespaceManager(xml.NameTable);
ns.AddNamespace("x", xml.DocumentElement.NamespaceURI);
var root = xml.DocumentElement;
var test = root.SelectSingleNode("//x:ScenarioDescription",ns);
var scenarioText = test.InnerText;
You can use the following code to access the ScenarioDescription node and its InnerText
var document = new XmlDocument();
document.Load(s);
var root = document.DocumentElement;
var node = root["ScenarioDescription"];
var text = node?.InnerText;
SelectSingleNode accepts the xpath expression, you simply can use XmlElement indexer instead. Otherwise you'll need to create a XmlNamespaceManager instance and add your root namespace to it
You can supply the XmlNamespaceManager object as a parameter to the
SelectNodes or SelectSingleNode method of the XmlDocument class to
execute XPath query expressions that reference namespace-qualified
element and attribute name

Use XmlReader to just get children

I have this XML:
<root>
<row>
<data1>Data</data1>
<data2>Data</data2>
<data3>Data
<subdata>SubData</subdata>
</data3>
</row>
</root>
and I want to use an XmlReader to read only the <dataX> elements, without knowing the exact name of dataX. I found the ReadToNextSibling method, but it needs a name, which I do not know.
You can use the following XPath to filter the elements to just the <dataN> elements:
/root/row/*[substring(name(), 0,5) = 'data']
/root/row/*[starts-with(name(),'data')]
However, XmlReader cannot use xPath nor wildcards for element names in any of its navigation methods such as ReadToNextSibling
You could use XPathReader, which can be instantiated from an XmlReader object, as follows:
XPathReader xpr = new XPathReader("MyXml.xml", "/root/row/*[substring(name(), 0,5) = 'data']");
while (xpr.ReadUntilMatch()) {
Console.WriteLine(xpr.ReadString());
}
(You can download XPathReader from Microsoft here: https://www.microsoft.com/en-us/download/details.aspx?id=22677)
If you don't like the idea of XPathReader, you can do the following with XmlDocument:
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(xml);
XmlNode root = xDoc.DocumentElement;
foreach (XmlNode item in root.SelectNodes(#"/root/row/*[substring(name(),0,5) = 'data']"))
{
Console.WriteLine(item.Value);
}
EDIT
A better XPath would actually be:
/root/row/*[starts-with(name(),'data')]

How to get value of a specific element in xml in c#

I have a xml file in below format
I want to fetch the value of Child1
When I am using below code it is providing a null value. Please help
XDocument xmlDoc = XDocument.Load(fileName);
XElement po = xmlDoc.Root.Element("Root");
XElement el1 = po.Element("Child1");
Use this:
xmlDoc.Descendants("Child1").First();

How to get data from an XML File in C# using XMLDocument class?

Good Evening All, and happy weekend!.
I have been trying all day to understand how to parse my simple XML file so I can understand it enough to write a personal project I want to work on.
I have been reading articles on this site and others but cannot get past where I am :(
My XML Document is ...
<XML>
<User>
<ID>123456789</ID>
<Device>My PC</Device>
</User>
<History>
<CreationTime>27 June 2013</CreationTime>
<UpdatedTime>29 June 2013</UpdatedTime>
<LastUsage>30 June 2013</LastUsage>
<UsageCount>103</UsageCount>
</History>
<Configuration>
<Name>Test Item</Name>
<Details>READ ME</Details>
<Enabled>true</Enabled>
</Configuration>
</XML>
I am trying to get the value in the details element (READ ME). Below is my code
// Start Logging Progress
Console.WriteLine("Test Application - XML Parsing and Creating");
Console.ReadKey();
// Load XML Document
XmlDocument MyDoc = new XmlDocument(); MyDoc.Load(#"E:\MyXML.XML");
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details");
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.Value));
// Pause
Console.ReadKey();
My console application is running and outputing "Target: " but not giving me the detail within the element.
Can somebody see why this is happening, and perhaps give me advice if I am completely off the wheel? I have no previous knowledge in reading XML files; hence where I am now :)
Thanks! Tom
With the your XPATH expression
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details");
your are selection an element so the type of the MyNode will be XmlElement but the Value of an XmlElement is always null (see on MSDN) so you need to use XmlElement.InnerText or XmlElement.InnerXml isntead.
So the changed your code to
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.InnerText));
Or you can select the content of an element with using the XPATH text() function, in this case MyNode will be XmlText where you get its value with Value:
// Select Node
XmlNode MyNode = MyDoc.SelectSingleNode("XML/Configuration/Details/text()");
// Output Node Value
Console.WriteLine(String.Concat("Details: ", MyNode.Value));
As a sidenote if you are anyway learning XML manipulation in C# you should check out LINQ to XML which is another/newer way to working with XML in C#.
Just for interest, a little-known "simple" syntax is this:
XmlDocument myDoc = new XmlDocument();
myDoc.Load(#"D:\MyXML.XML");
string details = myDoc["XML"]["Configuration"]["Details"].InnerText;
Note that this (and the XPath approach) could go pop if your XML doesn't conform to the structure you're expecting, so you'd ideally put some validation in there as well.
U can use Xpath library for that (u must include "System.Xml.XPath"):
XmlDocument document = new XmlDocument();
document.Load("MyXml.xml");
XPathNavigator navigator = document.CreateNavigator();
foreach (XPathNavigator nav in navigator.Select("//Details"))
{
Console.WriteLine(nav.Value);
}
the above code iterate over every node called (Details) extracting information and print it.
If you want to retrieve a particular value from an XML file
XmlDocument _LocalInfo_Xml = new XmlDocument();
_LocalInfo_Xml.Load(fileName);
XmlElement _XmlElement;
_XmlElement = _LocalInfo_Xml.GetElementsByTagName("UserId")[0] as XmlElement;
string Value = _XmlElement.InnerText;
Value contains the text value

Read first root node from XML

I work with three kinds of XML files :
Type A:
<?xml version="1.0" encoding="UTF-8"?>
<nfeProc versao="2.00" xmlns="http://www.portalfiscal.inf.br/nfe">
</nfeProc>
Tyepe B:
<?xml version="1.0" encoding="UTF-8"?>
<cancCTe xmlns="http://www.portalfiscal.inf.br/cte" versao="1.04">
</cancCTe>
Type C:]
<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.portalfiscal.inf.br/cte" versao="1.04">
</cteProc>
I have try with this code to read the first node :
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"C:\crruopto\135120068964590_v01.04-procCTe.xml");
XmlNodeList ml = xmlDoc.GetElementsByTagName("*");
XmlElement root = xmlDoc.DocumentElement;
exti = root.ToString();
but dont return anything i want to read the first node , need to know if the file is nfeProc ,canCTE or cteProc
The second question is how i get the value from "value" in the same tag???
Thanks
From this post:
//Root node is the DocumentElement property of XmlDocument
XmlElement root = xmlDoc.DocumentElement
//If you only have the node, you can get the root node by
XmlElement root = xmlNode.OwnerDocument.DocumentElement
I would suggest using XPath. Here's an example where I read in the XML content from a locally stored string and select whatever the first node under the root is:
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(xml));
XmlNode node = doc.SelectSingleNode("(/*)");
If you aren't required to use the XmlDocument stuff, then Linq is your friend.
XDocument doc = XDocument.Load(#"C:\crruopto\135120068964590_v01.04-procCTe.xml");
XElement first = doc.GetDescendants().FirstOrDefault();
if(first != null)
{
//first.Name will be either nfeProc, canCTE or cteProc.
}
Working with Linq to XML is the newest and most powerful way of working with XML in .NET and offers you a lot more power and flexibility than things like XmlDocument and XmlNode.
Getting the root node is very simple:
XDocument doc = XDocument.Load(#"C:\crruopto\135120068964590_v01.04-procCTe.xml");
Console.WriteLine(doc.Root.Name.ToString());
Once you have constructed an XDocument you don't need to use any LINQ querying or special checking. You simply pull the Root property from the XDocument.
Thanks i have solved this way the first part
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(nomear);
XmlNodeList ml = xmlDoc.GetElementsByTagName("*");
XmlNode primer = xmlDoc.DocumentElement;
exti = primer.Name;
First, to be clear, you're asking about the root element, not the root node.
You can use an XmlReader to avoid having to load large documents completely into memory. See my answer to a how to find the root element at https://stackoverflow.com/a/60642354/1307074.
Second, once the reader is referencing the element, you can use the reader's Name property to get the qualified tag name of the element. You can get the value as a string using the Value property.

Categories

Resources