Get value of an Xml attribute using Linq to Xml - c#

I have an XML like this:
<?xml version="1.0" encoding="utf-8"?>
<Projects>
<Project>
<Name>Projekt0</Name>
<Information>
<Version>1.0</Version>
<Info>test-project</Info>
<CreateDate>25.02.2015</CreateDate>
</Information>
<Files ID="1" path="D:\Data\ID1">
<file>one_file</file>
<file>another_file</file>
</Files>
<Files ID="2" path="D:\Data\ID2">
<file>someFile.txt</file>
</Files>
</Project>
</Projects>
It contains some more "Project"-Nodes, but that's not necessary.
First, I select a specific project by it's name. This works already, and is done this way:
var entries = from items in xelement.Elements("Project")
where (string)items.Element("Name").Value == projectName
select items;
entries contains now all the content of the wanted project.
One of my methods need to know the path-values of the both "Files"-Nodes.
I already tried something, but it's not working yet.
My first try was creating a new 'var' like 'entries', converting that to an array, and selecting the indices for saving the values as a string.
var path1 = from item in entries.Elements("Files")
where (string)item.Attribute("ID").Value == "1"
select item.Attribute("path").Value;
string path01 = path1.toArray()[0];
That is not working, and I'm not sure why. I'm sorry if that is a beginners question, but I haven't done a lot with xml & linq yet.
edit:
The lower 'entries' variable is the output of the first linq-code. So 'entries' contains a whole project.
Currently, path1 does not contain any elements.

entries is a sequence of Project nodes. Take Files child nodes before searching ID attribute
var path1 = from item in entries.Elements("Files")
where (string)item.Attribute("ID").Value == "1"
select item.Attribute("path").Value;

Related

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=\"(.*?)\"

How to get specific attributes from all xml files in directory?

I have a folder full of xml files. In these files many of them share a common attribute (Name), but have a secondary attribute that is different. I want to get a list of the unique entries based off reading these xml files. Below is an example of what the various xml files will contain.
File 1
<?xml version="1.0" encoding="UTF-8"?>
<results date="2013-12-29">
<A uniqueId="1234" Name="My-Machine"/>
<error number="555">
<description><![CDATA[House on Fire]]></description>
</error>
</results>
File 2
<?xml version="1.0" encoding="UTF-8"?>
<results date="2013-12-29">
<A uniqueId="1234" Name="My-Machine"/>
<error number="556">
<description><![CDATA[House in flood]]></description>
</error>
</results>
File 3
<?xml version="1.0" encoding="UTF-8"?>
<results date="2013-12-29">
<A uniqueId="1234" Name="My-Machine"/>
<error number="556">
<description><![CDATA[House in flood]]></description>
</error>
</results>
I need to be able to read all the files, add each Name and description to a list (or possibly array). Output from example would look like this:
Name="MyMachine", description="![CDATA[House is flooding]]";
Name="MyMachine", description="![CDATA[House on fire]]";
Name="MyMachine", description="![CDATA[House on fire]]";
It seems LINQ may be the best way to handle this since the files are very small in content.
Here is a way to read that description element content from one file:
var xDoc = XDocument.Load("Input.xml");
var name = "My-Machine";
var aElement = xDoc.Root.Element("A");
string description = null;
if ((string)aElement.Attribute("Name") == name)
description = (string)xDoc.Root.Element("error").Element("description");
It will return the element value when Name attribute value matches your name variable. Otherwise description will be null.

Linq to XML - how do I get this element value

Fairly simple one, but my knowledge is limited in this area. I'm using the following c# code to access the value of elements within my SGML and XML documents.
It's working fine when there is only one element with the given name in the document, but as soon as there are more than one element with the same name it throws an exception, obviously!
I need to use xpath or some other way of specifying the location of the element i'm trying to get the value of.
XDocument doc = XDocument.Load(sgmlReader);
string system = doc.Descendants("chapnum").Single().Value;
return system;
This works fine, if there is only one "chapnum" in the doc, but i need to specifically get the value of "chapnum" at the following nested location "dmaddres/chapnum".
How please?
Here is a sample of the xml doc. I'm trying to get the value of the "chapnum" element nested in the "dmaddress" element.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dmodule []>
<dmodule xmlns:dc="http://www.purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.s1000d.org/S1000D_2-3-1/xml_schema_flat/descript.xsd">
<idstatus>
<dmaddres>
<dmc><avee><modelic>xx</modelic><sdc>A</sdc><chapnum>29</chapnum>
<section>1</section><subsect>3</subsect><subject>54</subject><discode
>00</discode><discodev>AAA</discodev><incode>042</incode><incodev
>A</incodev><itemloc>D</itemloc></avee></dmc>
<dmtitle><techname>Switch</techname><infoname>Description of function</infoname>
</dmtitle>
<issno inwork="00" issno="001" type="new"/>
<issdate day="20" month="07" year="2012"/>
<language language="sx"/></dmaddres>
<status>
<security class="01"/><datarest><instruct><distrib>-</distrib><expcont
>Obey the national regulations for export control.</expcont></instruct>
<inform><copyright><para><refdm><avee><modelic>xx</modelic><sdc>A</sdc>
<chapnum>29</chapnum><section>1</section><subsect>3</subsect><subject
>54</subject><discode>00</discode><discodev>ZZZ</discodev><incode
>021</incode><incodev>Z</incodev><itemloc>D</itemloc></avee></refdm
></para></copyright><datacond>BREXREF=AJ-A-00-00-00-05ZZZ-022Z-D VERSUB=CDIM-V6</datacond>
</inform></datarest>
<rpc>xxxxx</rpc>
<orig>xxxxx</orig>
<applic>
<type>-</type>
<model model="xxxxx"><mfc>xxxxx</mfc><pnr>xxxxxxx</pnr></model>
</applic>
<brexref><refdm><avee><modelic>xx</modelic><sdc>A</sdc><chapnum>00</chapnum>
<section>0</section><subsect>0</subsect><subject>00</subject><discode
>05</discode><discodev>ZZZ</discodev><incode>022</incode><incodev
>Z</incodev><itemloc>D</itemloc></avee></refdm></brexref>
like this?
string system = doc.Descendants("dmaddres")
.Single(e => e.Element("chapnum") != null)
.Element("chapnum").Value;
string system = doc.Root.Element("dmaddres").Element("chapnum").Value;
would probably do just as well.

"Cannot Serialize Multidimensional Arrays" -What is it, and what did I type wrong?

I've been trying to Import XML files into my XNA project for quite a while.
Just when I thought that I'd gotten it all done, this error pops up. Lots of searching, and I haven't found an answer that helps.
This is a clipped version of my XML document:
<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
<!-- TODO: replace this Asset with your own XML asset data. -->
<Asset Type="Library.Room">
<Tile itIs="Wall">
<x>0</x>
<y>0</y>
<o>0</o>
</Tile>
</Asset>
</XnaContent>
When trying to Build, I get this Error:
"Building content threw RankException: Cannot serialize multidimensional arrays."
Even commenting out lines of my project code do nothing to change this error, so I know that it's something in how I've written my XML. ( Which I thought was okay )
So, that tells me that I'm probably writing my XML wrong. What is a MultiDimensional Array in XML, and how can I avoid it?
___Added Info
I add the XML info to an Array here, piece by piece. --naturally, I thought that this was the problem at first, but commenting any of this out has no effect.
public void loadFromFile(string fileName, Room r)
{
var doc = XElement.Load(fileName);
foreach (var v in roomDoc.Elements("Tile"))
{
r.blueprint.SetValue(new Things.Wall((int)v.Element("o")), (int)v.Element("x"), (int)v.Element("y"));
}
}

XDocument.Descendants(itemName) - Problems finding qualified name

I'm trying to read a XML-RSS-Feed from a website. Therefore I use a async download and create a XDocument with the XDocument.Parse() Method.
The Document intends to be very simple, like this:
<root>
<someAttribute></SomeAttribute>
<item>...</item>
<item>...</item>
</root>
Now I want to read out all the items. Therefore I tried:
foreach (XElement NewsEntry in xDocument.Descendants("item"))
but this doesn't work. So I found a post in this board to use the qualified name, because there are some namespaces defined in the root element:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns="http://purl.org/rss/1.0/">
well, I tried all 3 available namespaces - nothing worked for me:
XName itemName = XName.Get("item", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
XName itemName2 = XName.Get("item", "http://purl.org/dc/elements/1.1/");
XName itemName3 = XName.Get("item", "http://purl.org/rss/1.0/modules/syndication/");
Any help would be appreciated.
(Usually I'm doing the XML-Analysis with Regex - but this time I'm developing for a mobile device, and therefore need to care about performance.)
You have not tried the default namespace at the end of the rdf declaration:
xmlns="http://purl.org/rss/1.0/"
This makes sense, as any element in the default namespace will not need to have the namespace prepended to the element name.
Not directly a solution to the XDocument RSS read problem. But why aren't you using the provided SyncdicationFeed class to load the feed? http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.syndicationfeed.aspx
Try this
var elements = from p in xDocument.Root.Elements()
where p.Name.LocalName == "item"
select p;
foreach(var element in elements)
{
//Do stuff
}

Categories