accessing special element in xml using linq [duplicate] - c#

This question already has answers here:
LINQ to read XML
(6 answers)
Closed 8 years ago.
how can I get Password value for specified Username using linq?
For example if Username equals AAAA then passsword is ss.
<?xml version="1.0" encoding="utf-8"?>
<User>
<Username>AAAA</Username>
<Password>ss</Password>
</User>
<User>
<Username>CCC</Username>
<Password>zzz</Password>
</User>

I will start by saying you should change your xml structure to the following:
<?xml version="1.0" encoding="utf-8"?>
<users>
<User>
<Username>AAAA</Username>
<Password>ss</Password>
</User>
<User>
<Username>CCC</Username>
<Password>zzz</Password>
</User>
</users>
Then you can try:
var username = "AAAA";
var password = XElement.Parse(xml)
.Elements("User")
.Where(x=>(string)x.Element("Username") == username)
.Select(x=>(string)x.Element("Password"));
I tend to use XElement, but some would say XDocument is better:
var xdoc = XDocument.Parse(xml);
var username = "AAAA";
var password = xdoc.Root.Elements("User")
.Where(x=>(string)x.Element("Username") == username)
.Select(x=>(string)x.Element("Password"))
.FirstOrDefault();

Related

C# search tag in XML and show another tag

I have the following XML-File.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Contacts>
<Contact>
<Name>Example</Name>
<PhoneNo>0481-12345678</PhoneNo>
<SalesPhoneNo>310<SalesPhoneNo />
</Contact>
</Contacts>
Would it be possible to search for the PhoneNo 0481-12345678 in the XML and then only show the SalesPhoneNo 310.
You could use an XPath query to do this. For example,
var xml = #"<Contacts>
<Contact>
<Name>Example</Name>
<PhoneNo>0481-12345678</PhoneNo>
<SalesPhoneNo>310</SalesPhoneNo>
</Contact>
</Contacts>";
XDocument xDoc = XDocument.Parse(xml);
// this will return 310
string phoneNo = '0481-12345678';
var salesPhoneNo = xDoc.XPathEvaluate("string(//Contact[PhoneNo='" + phoneNo + "']/SalesPhoneNo)");
Note you need to add a using System.Xml.XPath to use XPath query on an XDocument

C# Parsing specific xml

I wonder how do I parse a specific person by the id in the xml below?
Also lets say I wanna loop through them all and add them to a listview, How do I do that with XmlDocument?
<users>
<user id="Marcus">
<website>www.google.com</website>
<type>1</type>
</user>
<user id="John">
<website>www.youtube.com</website>
<type>1</type>
</user>
<user id="Josh">
<website>www.google.com</website>
<type>2</type>
</user>
</users>
Here's a linq to xml example -
using System.Xml.Linq;
var doc = XDocument.Parse(#"...");
var element = doc.XPathSelectElement("/users/user[#id='John']");
var website = element.XPathSelectElement("website").Value;
var type = int.Parse(element.XPathSelectElement("type").Value);

XPathSelectElements => string representation

Hi because of a misunderstanding I want to ask my question again.
I have the following XML structure:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<root>
<Item>
<taxids>
<string>330</string>
<string>374</string>
<string>723</string>
<string>1087</string>
<string>1118</string>
<string>1121</string>
</taxids>
</Item>
</root>
</xml>
I need to get all the string nodes from the xml file to a string variable.
I want to get a string like this:
<taxids><string>330</string><string>374</string><string>723</string><string>1087</string><string>1118</string><string>1121</string></taxids>
My linq to xml:
var query = from ip in doc.XPathSelectElements("xml/root/Item")
select ip.XPathSelectElement("taxids").ToString();
But I am getting the following in one row of the variable query:
"System.Xml.XPath.XPathEvaluator+<EvaluateIterator>d__0`1[System.Xml.Linq.XElement]"
Is this possible?
Thanks!
Try this:
var result = doc.Element("xml")
.Element("root")
.Element("Item")
.Element("taxids")
.ToString(SaveOptions.DisableFormatting);
// result == "<taxids><string>330</string><string>374</string> ... </taxids>"

insert node in xml file

i have a xml file that looks like the following, and i need to edit it in c# to insert a new node:
<?xml version="1.0" encoding="utf-8"?>
<Users>
<User>
<Name>John Smith</Name>
<test>
<Date>23.05.2011</Date>
<points>33</points>
</test>
<test>
<Date>22.06.2011</Date>
<points>29</points>
</test>
</User>
<User>
<Name>David Chris</Name>
<test>
<Date>01.02.2009</Date>
<points>25</points>
</test>
<test>
<Date>14.01.2010</Date>
<points>231</points>
</test>
</User>
i need to insert another "in this example a third" Element to the user called "John Smith" with all the sub elements..
so the xml will become :
<?xml version="1.0" encoding="utf-8"?>
<Users>
<User>
<Name>John Smith</Name>
<test>
<Date>23.05.2011</Date>
<points>33</points>
</test>
<test>
<Date>22.06.2011</Date>
<points>29</points>
</test>
<test>
<Date>30.10.2011</Date>
<points>21</points>
</test></b>
</User>
<User>
<Name>David Chris</Name>
<test>
<Date>01.02.2009</Date>
<points>25</points>
</test>
<test>
<Date>14.01.2010</Date>
<points>231</points>
</test>
</User>
any help is really appreciated ..
thanks a lot ..
Simple (assuming you're using .NET 3.5 or higher):
Load the document (e.g. using XDocument.Load)
Add the relevant element (create a new XElement, find the insertion point, call insertionPoint.Add(newElement))
Save the document (XDocument.Save)
LINQ to XML makes almost all XML-based tasks simpler than older APIs... if the above isn't a good enough start, I'd strongly recommend reading a tutorial on LINQ to XML.
There's no simple way of inserting the new element without reading the old file totally, manipulating it and then writing it out totally. In theory you could do it in a streaming fashion with XmlReader and XmlWriter, but they're almost always more trouble than they're worth.
class Program
{
static void Main()
{
var doc = XDocument.Load("test.xml");
var johnSmith = doc
.Descendants("User")
.Descendants("Name")
.Where(x => x.Value == "John Smith")
.Select(x => x.Parent)
.First();
johnSmith.Add(
new XElement("test",
new XElement("Date", "30.10.2011"),
new XElement("points", "21")
)
);
doc.Save("new.xml");
}
}
For .NET Framework 3.5 and higher: XDocument
For .NET Framework 1.1 and higher: XmlDocument
Here you go:
class Program
{
static void Main(string[] args)
{
XElement main = XElement.Load(#"users.xml");
// write new data to new file
string newDate = "01.01.2012";
string newPoints = "42";
main.Descendants("User")
.Descendants("Name")
.Where(e => e.Value == "John Smith")
.Select(e => e.Parent)
.First()
.Add(new XElement("test",
new XElement("date", newDate),
new XElement("points", newPoints)
)
);
main.Save("users2.xml");
}
}

Deleting whole sections of my XML file

I have a userlist for a program I'm designing, and all the users are stored to an XML file, like so:
<?xml version="1.0"?>
<Users>
<User ID="1">
<nickname>Tom</nickname>
<password>Sams</password>
<host>ahost#asd.com</host>
<email>badrandom#as.com</email>
<isloggedin>true</isloggedin>
<permission>10</permission>
</User>
<User ID="2">
<nickname>ohai</nickname>
<password>asdalkdj9u</password>
<host>meh#meh.com</host>
<email>my#email</email>
<isloggedin>false</isloggedin>
<permission>1</permission>
</User>
<User ID="3">
<nickname>ohai</nickname>
<password>sercret</password>
<host>my#host</host>
<email>my#email</email>
<isloggedin>false</isloggedin>
<permission>1</permission>
</User>
<User ID="4">
<nickname>mib_hr6qhr</nickname>
<password>YXNsa2RhZGxrYXNk</password>
<host>adb7e51b#webchat.mibbit.com</host>
<email>alskd#alskd.com</email>
<isloggedin>true</isloggedin>
<permission>1</permission>
</User>
</Users>
Now, based on the users ID number, I need to be able to delete all reference to that user.
So say, I have ID number 3, how can I completely delete userid number 3's existence from the xml file?
I'm looking for code examples, but any help would be greatly appreciated!
One approach using the XML DOM (.NET 1.x and up) would be to just load the file, find user no. 3, and remove that node, and save the file back:
XmlDocument doc = new XmlDocument();
doc.Load("yourXmlFile.xml");
XmlNode userNo3 = doc.SelectSingleNode("//Users/User[#ID='3']");
if(userNo3 != null)
{
userNo3.ParentNode.RemoveChild(userNo3);
}
doc.Save("YourNewXmlFile.xml");
Marc
Assuming you have the XML loaded in an XDocument:
using System.Linq;
using System.Xml.Linq;
void Delete()
{
XDocument document = LoadXML();
document.Elements("Users")
.Single(e => e.Attribute("ID").Value == "3")
.Remove();
}
Of course, this assumes that the user you request will always be present in the XML. To be safe, you should use SingelOrDefault() and check for a null value before deleting.
The problem with linq and DOM approach is that there is a round-trip (parsing/serialization) which can be efficient, vtd-xml has something called incremental update, here is an article that explains it... http://www.codeproject.com/KB/XML/xml_processing_future.aspx
VTDGen vg = new VTDGen();
if (vg.parseFile("your.xml", false)){
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/users/user[#ID='3']");
XMLModifier xm = new XMLModifier(vn);
if (ap.evalXPath()!=-1){
xm.remove();
xm.output("new.xml");
}
}

Categories