XDocument to XElement - c#

How do you convert an XDocument to an XElement?
I found the following by searching, but it's for converting between XDocument and XmlDocument, not XDocument and XElement.
public static XElement ToXElement(this XmlElement xmlelement)
{
return XElement.Load(xmlelement.CreateNavigator().ReadSubtree());
}
public static XmlDocument ToXmlDocument(this XDocument xdoc)
{
var xmldoc = new XmlDocument();
xmldoc.Load(xdoc.CreateReader());
return xmldoc;
}
I couldn't find anything to convert an XDocument to an XElement. Any help would be appreciated.

Other people have said it, but here's explicitly a sample to convert XDocument to XElement:
XDocument doc = XDocument.Load(...);
return doc.Root;

XDocument to XmlDocument:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xdoc.CreateReader());
XmlDocument to XDocument
XDocument xDoc = XDocument.Load(new XmlNodeReader(xmlDoc));
To get the root element from the XDocument you use xDoc.Root

Simple conversion from XDocument to XElement
XElement cvtXDocumentToXElement(XDocument xDoc)
{
XElement xmlOut = XElement.Parse(xDoc.ToString());
return xmlOut;
}

Related

Convert XMLDocument to XDocument ,getting names spaces Modifing from xsi to p1

i create an XMLDocument:
`
XmlDocument doc = new XmlDocument();
XmlDeclaration declaire = doc.CreateXmlDeclaration("1.0", "utf-8", null);
// -----------------------create root-----------------------------
XmlElement rootnode = doc.CreateElement( "BMECAT");
doc.InsertBefore(declaire, doc.DocumentElement);
doc.AppendChild(rootnode);
//Console.WriteLine(sb.ToString());
//get attribute for BmeCat
rootnode.SetAttribute("version", "2005");
XmlAttribute atr = doc.CreateAttribute("xsi", "schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
atr.Value = "http://www.adlnet.org/xsd/adlcp_v1p3";
rootnode.SetAttributeNode(atr);
rootnode.Attributes.Append(atr);`
then i convert it to XDocument using the function below but i get a NameSpace changed like this
XDocument ToXDocument(XmlDocument xmlDocument)
{
using (var nodeReader = new XmlNodeReader(xmlDocument))
{
nodeReader.MoveToContent();
return XDocument.Load(nodeReader);
}
}
`
below the xml and the XDocument
<?xml version="1.0" encoding="utf-8"?>
<BMECAT version="2005" p1:schemaLocation="http://www.adlnet.org/xsd/adlcp_v1p3" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance">
<?xml version="1.0" encoding="utf-8"?>
<BMECAT version="2005" xsi:schemaLocation="http://www.adlnet.org/xsd/adlcp_v1p3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
You need to explicitly add the xsi namespace declaration manually at the beginning of your element.
Nodes are processed in document order and the namespace declaration appears later after it is first used. It doesn't know to use xsi for the prefix until it's too late.
var doc = new XmlDocument();
doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));
var root = (XmlElement)doc.AppendChild(doc.CreateElement("BMECAT"));
var xsi = "http://www.w3.org/2001/XMLSchema-instance";
root.SetAttribute("xmlns:xsi", xsi); //set the namespace now
root.SetAttribute("schemaLocation", xsi, "http://www.adlnet.org/xsd/adlcp_v1p3");
root.SetAttribute("version", "2005");

iterating XmlDocument with xpath

How do we iterate an XmlDocument using an xpath?
I'm attempting to return a list of nodes by xpath:
public static List<string> Filter(string xpath, string input, string ns, string nsUrl)
{
var bytes = Encoding.UTF8.GetBytes(input); //i believe this unescapes the string
var stream = new MemoryStream(bytes);
var doc = new XmlDocument();
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
namespaceManager.AddNamespace(ns, nsUrl);
var links = new List<string>();
var nodes = doc.SelectNodes(xpath, namespaceManager);
using (var reader = new XmlTextReader(stream))
{
reader.Namespaces = false;
doc.Load(reader);
}
foreach (XmlNode node in nodes)
{
if (IsNullOrWhiteSpace(node.InnerText))
{
continue;
}
links.Add(node.InnerText);
}
return links;
}
however, the count is always 0 !
I'm using this xpath. notice how i am using only 1 namespace:
/ns0:Visit/ns0:DocumentInterface/ns0:Documents/ns0:Document/ns0:BinaryData
The header of the file looks like this:
<ns0:Visit xmlns:ns0="http://NameSpace.ExternalSchemas.Patient"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
I'm certain that I am using the right xpath because I tested it against my payload:
I'm calling the function this way:
var links = Filter(xpath, xml, "ns0", "http://NameSpace.ExternalSchemas.Patient");
How do we iterate an XmlDocument using an xpath? Perhaps the XmlDocument should be an XDocument instead?

XmlDocument - SelectSingleNode with namespace

This is my code:
XmlTextReader reader = new XmlTextReader(xmlPath);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNode root = xmlDoc.DocumentElement;
XmlNode node = root.SelectSingleNode("marketingid");
XML that works:
<confirmsubmit>
<marketingid>-1</marketingid>
</confirmsubmit>
XML that doesn't work:
<confirmsubmit xmlns="http:....">
<marketingid>-1</marketingid>
</confirmsubmit>
What is the way to deal with the xmlns attribute and how can i parse it?
Is it has anything to do with namespace?
EDIT:
This is the code that works:
XmlTextReader reader = new XmlTextReader(xmlPath);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", xmlDoc.DocumentElement.NamespaceURI);
XmlNode book = xmlDoc.SelectSingleNode("/ns:confirmsubmit/ns:marketingid", nsmgr);
This all XPath is more complicated than seems, I would recommand to begginers like my to read: http://www.w3schools.com/xpath/xpath_syntax.asp
You need to add a XmlNamespaceManager instance in the game, as shown in this example from the documentation:
public class Sample
{
public static void Main()
{
XmlDocument doc = new XmlDocument();
doc.Load("booksort.xml");
//Create an XmlNamespaceManager for resolving namespaces.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bk", "urn:samples");
//Select and display the value of all the ISBN attributes.
XmlNodeList nodeList;
XmlElement root = doc.DocumentElement;
nodeList = root.SelectNodes("/bookstore/book/#bk:ISBN", nsmgr);
foreach (XmlNode isbn in nodeList){
Console.WriteLine(isbn.Value);
}
}
}
Here is how to do it from LINQ to XML. Short and simple
const string xml = #"<confirmsubmit xmlns='http:....'>
<marketingid>-1</marketingid>
</confirmsubmit>";
XElement element = XElement.Parse(xml);
var requestedElement = element.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("marketingid"));
xmlns attribute is used at XHTML and defines namespace for a document. You can parse it like:
XDocument xdoc = XDocument.Load(xmlPath);
var attrib = xdoc.Root.Attribute("xmlns").Value;

How to set attribute to an XML element using linq to xml in C#

i've an xml file like
<Root>
<Steps>
<Step Test="SampleTestOne" Status="Fail" />
<Step Test="SampleTestTwo" Status="Fail" />
</Steps>
</Root>
i need to change or overwrite the attribute value of "Status" in the Step element.
Now i'm using XmlDocument for this
like
XmlDocument XDoc = new XmlDocument();
XDoc.Load(Application.StartupPath + "\\Sample.xml");
XmlNodeList NodeList = XDoc.SelectNodes("//Steps/Step");
foreach (XmlNode Node in NodeList)
{
XmlElement Elem = (XmlElement)Node;
String sTemp = Elem.GetAttribute("Test");
if (sTemp == "SampleTestOne")
Elem.SetAttribute("Status", "Pass");
}
I need search the element and to update the status
is there any way to do this using XDocumentin c#
Thanks in advance
string filename = #"C:\Temp\demo.xml";
XDocument document = XDocument.Load(filename);
var stepOnes = document.Descendants("Step").Where(e => e.Attribute("Test").Value == "SampleTestOne");
foreach (XElement element in stepOnes)
{
if (element.Attribute("Status") != null)
element.Attribute("Status").Value = "Pass";
else
element.Add(new XAttribute("Status", "Pass"));
}
document.Save(filename);
You can use this code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFile);
XmlNode node = xmlDoc.SelectSingleNode("Root/Steps/Step");
node.Attributes["Status"].Value = "True";
xmlDoc.Save(xmlFile);

Enumerating Linq.Xelement

How to adjust this code to work when RESPONSE is no more string but Linq.Xelement?
String response = "anyxml data";
XmlDocument xmlDocument = LoadXMLDocument(response);
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("fql_query_response");
if (nodeList != null && nodeList.Count > 0)
{
if (nodeList[0].HasChildNodes)
{
XmlNodeList results = xmlDocument.GetElementsByTagName("event_member");
Dictionary<string, EventUser> eventUserDict = new Dictionary<string, EventUser>();
foreach (XmlNode node in results)
{
myuids.Add(Int64.Parse(node.FirstChild.InnerText));
}
}
Do you mean you want to create an XmlDocument from an XElement?
The simplest way to do that may well be this:
XmlDocument doc = new XmlDocument();
using (XmlReader reader = element.CreateReader())
{
doc.Load(reader);
}
However, I have to say the code would probably be simpler if you just converted it all to LINQ to XML, which is generally a nicer API to start with. Is there any reason why you want to stay with XmlDocument?
You can use XElement.ToString() to create an XML string from the XElement which you can load into your XmlDocument:
XmlDocument xmlDocument = LoadXMLDocument(yourXElement.ToString());

Categories