I am trying to get the variable whitch is an integer, but it gives me a string.
XDocument xmlDoc = XDocument.Load(path);
var test = xmlDoc.Descendants("Variables").Elements("nom").Select(e => (int)e);
Console.WriteLine(test);
here is my xml file
<?xml version="1.0" encoding="utf-8"?><Variables><Site>Chand</Site><nom>12</nom></Variables>
The expression you entered is of type IEnumerable<int> and not a single int. Try appending .First() to get the first (and in this case only) element of the enumerable.
var test = xmlDoc.Descendants("Variables").Elements("nom").Select(e => (int)e).First();
Related
I am editing an existing XML file. I cannot edit an element (the element “range”) that is a multiple value element (a list or an array?), as shown in the XML code below.
<objects>
<PinJoint name="revolute">
<socket_parent_frame>torso_offset</socket_parent_frame>
<socket_child_frame>base_offset</socket_child_frame>
<coordinates>
<Coordinate name="revolute_angle">
<default_value>0</default_value>
<default_speed_value>0</default_speed_value>
<range>-1.5700000000000001 1.5700000000000001</range>
<clamped>true</clamped>
<locked>true</locked>
</Coordinate>
</coordinates>
I want to rewrite the values of the element “range”. In this case, these are two numeric values (doubles) separated by spaces.
I am trying to do this with the following c# code
XDocument xdoc = XDocument.Load(#"G:/My Drive/File.xml");
double r1 = new double[,] { {0.1745, 1.3963 } };
var pinjoints = xdoc.Root.Descendants("objects").Elements("PinJoint").Descendants("coordinates").Elements("Coordinate").FirstOrDefault(x => x.Attribute("name").Value == "revolute_angle");
pinjoints.SetElementValue("range", r1);
but the “range” element is rewritten as follow:
<range>System.Double[,]</range>
Can you please help me to edit the element “range” by rewriting one or all its numeric values?
Best regards
Andrés
You are passing array(r1) to the XML element as a value. XML elements accept string.
You can replace your code with the following code & it should work.
XDocument xdoc = XDocument.Load(#"G:/My Drive/File.xml");
double[] r1 = new double[] {0.1745, 1.3963 };
var str = string.Join(",",r1);
var pinjoints = xdoc.Root.Descendants("objects").Elements("PinJoint").Descendants("coordinates").Elements("Coordinate").FirstOrDefault(x => x.Attribute("name").Value == "revolute_angle");
pinjoints.SetElementValue("range", str);
Here, I have just used string.Join() method to produce comma separated string that can be easily passed to XML element.
I am building an XDocument and I have unit tests to test the output. One of the things I want to test for is that invalid strings are being formatted for XML properly. I have discovered that calling .ToString() on the XDoc itself properly formats the invalid strings for XML. However, in my testing I am retrieving specific Elements or Attributes off of the XDoc and testing the values. This does not format the values for XML. How do I go about getting these values in their escaped format?
Answer: (thx Ed Plunkett)
myXDoc.Descendants("element2").First().FirstNode.ToString();
// result "Pork&Beans"
Sample:
var xml =
"<element1>" +
"<element2>Pork&Beans</element2>" +
"</element1>";
var myXDoc = XDocument.Load(xml);
var xDocString = myXDoc.ToString();
// result is formatted - <element1> <element2>Pork&Beans</element2> </element1>
var element2Value = myXDoc.Decendents("element2").First().Value;
// result is unformatted - Pork&Beans
Got it: Text elements in XML are nodes too.
var el2XML = myXDoc.Descendants("element2").First();
var porkAndAmpSemicolonBeans = el2XML.FirstNode.ToString();
You'll want to also check el2XML.Nodes.Count to make sure there's exactly one child in there.
System.Xml.XmlDocument is another option, because XmlNode has an InnerXml property that'll give you what you want:
var morePorkAndBeans = doc.SelectSingleNode("//element2").InnerXml;
How can I get elements of a certain name from an XML document as an XML String? (with XDocument)
I.e, say I have this:
<root>
<orange id="orange1"></orange>
<orange id="orange2"></orange>
<orange id="orange3"></orange>
<apple id="apple1"></apple>
<apple id="apple2"></apple>
<apple id="apple3"></apple>
</root>
How can I get only the XML for the apples? Ie the XML string for those three lines?
My current code is:
using (TextReader reader = File.OpenText(xmlFilePath))
{
XDocument xmlDocument = XDocument.Load(reader);
string items = xmlDocument.Descendants("apple").ToString();
}
...but in this example, items ends up as: System.Xml.Linq.XContainer+<GetDescendants>d__a rather than the XML string. I can't seem to find any method which will give me back the XML for the matched elements.
The problem is that you're calling ToString() on the result of calling Descendants(). It's not really clear what you expected that to do, but you are getting the elements correctly. For example:
using (TextReader reader = File.OpenText(xmlFilePath))
{
// Any reason for not using XDocument.Load(xmlFilePath)?
XDocument xmlDocument = XDocument.Load(reader);
var items = xmlDocument.Descendants("apple");
foreach (var item in items)
{
Console.WriteLine(item.Attribute("id").Value); // Or whatever
}
}
If you want to concatenate the results of converting each XElement to string, you could use:
var items = string.Join("", xmlDocument.Descendants("apple"));
or
var items = string.Concat(xmlDocument.Descendants("apple"));
Use String.Concat(xmlDocument.Descendants("apple")).
You are using ToString() on a collection of xml elements, hence your results. If I'm reading your requirements correctly, you need something like:
var items = String.Join(Environment.NewLine,
xmlDocument.Descendants("apple")
.Select(e => e.ToString()));
I have an xml string and have different records within and i want to extract the id within each record. Here is a sample of the xml:
<UploadsInformation >
<Record>
<TaskGUID>48A583CA-A532-419A-9CDB-292764CEC541</TaskGUID>
</Record>
<Record>
<TaskGUID>ED6BA682-2BB2-4ADF-8355-9C605E16E088</TaskGUID>
</Record>
<Record>
<TaskGUID>D20D7042-FC5B-4CF7-9496-D2D9DB68CF52</TaskGUID>
</Record>
<Record>
<TaskGUID>F5DB10C5-D517-4CDA-8AAA-4E3F50B5FF3C</TaskGUID>
</Record>
</UploadsInformation>
This is what i have as a string to extract the information that i need but not sure if it correct or not because when i debug the string seems to be the xml file and not just the specified guid.
string data = new XDocument(new XElement("Record",
uploads.Select(guid => new XElement("TaskGUID", guid.ToString()))))
.ToString();
uploads is: List<Guid?> uploads
If I understand your question correctly, you want to extract the Guids from the source XML, which you indicate is a string.
You can create an XDocument from a string with the following command:
XDocument doc = XDocument.Parse(xmlString);
XNamespace ns = "http://schemas.acatar.com/2013/03/Malt.Models";
List<string> uploads = doc.Descendants(ns + "TaskGUID")
.Select(x => x.Value).ToList();
string uploadString = String.Join(",", uploads);
I used XNamespace because there is a namespace (two, actually) defined in the XML, and unless you prefix the correct one to the element name you won't get any results.
You might be able to combine the last two steps into one line, but I'm not 100% sure.
The above code was tested with your example, and produces the following value for uploadString:
48A583CA-A532-419A-9CDB-292764CEC541,ED6BA682-2BB2-4ADF-8355-9C605E16E088,D20D7042-FC5B-4CF7-9496-D2D9DB68CF52,F5DB10C5-D517-4CDA-8AAA-4E3F50B5FF3C
However, if you're going to loop through the result and pass each one in singularly to a stored procedure, I'd skip the String.Join and just loop through the List:
foreach (string id in uploads)
{
// Do your stored procedure call for each Guid.
}
Added in Response to Comment
In the situation in your comment, if you have a List that you want to get the values for, you'd do essentially the same, but you'll need to check for nulls and (probably) convert the Guid to a string before passing it into the stored proc:
foreach (Guid? g in uploads)
{
if (g != null)
{
string newGuid = g.ToString();
// do your data access stuff here
}
}
You can't use local names of elements, because you have namespace declared. So, you should use namespace to provide names:
XNamespace ns = "http://schemas.acatar.com/2013/03/Malt.Models";
var guids = from r in xdoc.Root.Elements(ns + "Record")
select Guid.Parse((string)r.Element(ns + "TaskGUID"));
Or query your xml without specifying names of elements:
var guids = xdoc.Root.Elements()
.Select(r => Guid.Parse((string)r.Elements().Single()));
I think this is either what you are after or perhaps might shed some light on the direction to go:
string xml = ""; // XML data here
XDocument doc = XDocument.Parse(xml);
List<Guid> guids = doc.Descendants("TaskGUID")
.Select(g => new Guid(g.Value))
.ToList();
I would like to parse this XML :
<?xml version="1.0" encoding="Windows-1252" ?>
<TEST>Login inexistant</TEST>
I wrote this code
var result = from item in XElement.Parse(m_strRetour).Descendants("TEST")
select item;
return result.First().ToString();
m_strRetour is a string that contains my XML.
After execution, result is empty.
What am I doing wrong?
TEST seems to be your root node, so it can't be a Descendant.
To get the value out of it you could try this.
var xml = "<?xml version='1.0' encoding='Windows-1252' ?><TEST>Login inexistant</TEST>";
var result = XElement.Parse(xml);
var value = result.Value;
XElement.Parse will return the TEST element itself - which doesn't have any descendants. (Also, there's no benefit in using a query expression here. Whenever you write from x in y select x you should consider whether you couldn't just use y instead...)
You could parse it as an XDocument instead, in which case there would be a TEST descendant... or you could just use the XElement itself.
What are you really trying to achieve though? Does your real XML only have a single element?