How do you create standalone XML nodes in .NET? - c#

How do you create a standalone XML node in .NET?
I have an XMLElement type that I'm trying to set a value to, but since the constructor for that class is protected, it won't let me do it.
This is what I'm currently doing:
XmlDocument xmldoc = new XmlDocument();
XmlElement foo = xmldoc.CreateElement("", "foo"); ;
XmlElement bar = xmldoc.CreateElement("", "bar"); ;
Is there a better way to do this?

If you use XElement from System.Xml.Linq instead of the old XmlElement from System.Xml it allows you to do that very easily:
new XElement("foo")

you can try this
public XElement ToXml()
{
XElement element = new XElement("Song",
new XElement("", "foo"),
new XElement("", "bar"));
return element;
}

I've done this in the past:
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
XmlElement fundsElement = doc.CreateElement("funds");
doc.AppendChild(fundsElement);

Are you on .NET 3.5 or later?
using System.Xml.Linq;
var element = new XElement("foo", "bar");
Console.WriteLine(element.ToString());
Output:
<foo>bar</foo>

Related

Copy Node and change Value of an Attribute

I have the following XML File. I want to copy a new "Test" and change the ID of the Test. How is it possible?
I already can copy the nodes, unfortunately not on the correct position (see images) and I also can´t change the ID.
Anyone have a solution for me?
Before:
After:
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(Before.xml");
XmlNode Set = xmldoc.DocumentElement;
string strXmlQuery = "/Toolings/Testing/Test1";
XmlNode NodeToCopy = Set.SelectSingleNode(strXmlQuery);
XmlNode NewNode = NodeToCopy.CloneNode(true);
NodeToCopy.AppendChild(NewNode);
Set.InsertAfter(NewNode, Set.LastChild);
XPathNavigator navigator = xmldoc.CreateNavigator();
navigator.MoveToRoot();
navigator.MoveToFirstChild();
navigator.MoveToFirstChild();
navigator.MoveToFirstChild();
navigator.MoveToFirstChild();
navigator.SetValue("5678");
xmldoc.Save(After.xml");
Here is an example using System.Xml.Linq.XDocument which is a much easier API than XmlDocument:
//You can also use Load(), this is just so I didn't have to make a file
XDocument doc = XDocument.Parse("<Toolings><Testing><Test><ID>1234</ID></Test></Testing></Toolings>");
//Grab the first Test node (change the predicate if you have other search criteria)
var elTest = doc.Descendants().First(d => d.Name == "Test");
//Copy the node, only necessary if you don't know the structure at design time
XElement el = new XElement(elTest);
el.Element("ID").Value = "5678";
//inject new node
elTest.AddAfterSelf(el);
doc.Save("After.xml");

Alternatives for System.Xml.Linq to match Xpath

I have used System.Xml.Linq; to match Xpath from xml document. XElement and SaveOptions both get from System.Xml.Linq;.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
nsmgr.AddNamespace("ns", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-03T16:54:46");
XElement docRfsid = XElement.Parse(content);
//if (docRfsid.XPathSelectElement("//ns:RFSID", nsmgr).Value != null)
if (Regex.Match(docRfsid.ToString(), "RFSID", RegexOptions.IgnoreCase).Success)
{
projData.RfsId = docRfsid.XPathSelectElement("//ns:RFSID", nsmgr).Value.ToString();
}
XElement doc_Financial = XElement.Parse(content);
string resultFinancial = doc_Financial.XPathSelectElement("//ns:Financial", nsmgr).ToString(SaveOptions.DisableFormatting);
I just want to remove System.Xml.Linq; dll since I have to use .net framework 2.0 only.
Is there any other alternatives that I can use to System.Xml.Linq;.
Yes. Use System.Xml.XmlDocument, specifically the SelectNodes() method on it, the DocumentElement property or any XmlElement instance. This method accepts an XPath and returns a list of XmlElements that match (whether they be nodes (XmlNode) or attributes (XmlAttribute)). This is based off the old COM XmlDocument object and is available as far back as version 1.1 of the framework.
System.Xml
Something like
XmlDocument doc = new XmlDocument();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ns", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-02-03T16:54:46");
XmlNode financialNode = doc.DocumentElement.SelectNode("ns:Financial",nsmgr);
strring resultFinancial = null;
if (financialNode != null)
{
resultFinancial = financialNode.InnerText;
}
Sort of thing.

Xml with two attributes in C#

I want to make xml element like this:
<ElementName Type="FirstAttribute" Name="SecondAttribute">Value</Atrybut>
Now I'm doing this in this way:
XmlNode xmlAtrybutNode = xmlDoc.CreateElement("ElementName ");
_xmlAttr = xmlDoc.CreateAttribute("Type");
_xmlAttr.Value = "FirstAttribute";
xmlAtrybutNode.Attributes.Append(_xmlAttr);
_xmlAttr = xmlDoc.CreateAttribute("Name");
_xmlAttr.Value = "SecondAttribute";
xmlAtrybutNode.Attributes.Append(_xmlAttr);
xmlAtrybutNode.InnerText = !string.IsNullOrEmpty(Value)
? SetTextLength(Name, ValueLength)
: string.Empty;
Value is input variable in method.
Is there possibility to make this in another way?
More efficiently?
Can I use xmlWriter? Now i'm using xmlDocument.
You can use Linq to XML.
Basically
XDocument doc = new XDocument();
doc.Add(
new XElement("ElementName", "Value",
new XAttribute("Type", "FirstAttribute"),
new XAttribute("Name", "SecondAttribute")));
will give this xml document
<ElementName Type="FirstAttribute" Name="SecondAttribute">Value</ElementName>
How about tweaking your existing code:
XmlElement el = xmlDoc.CreateElement("ElementName");
el.SetAttribute("Type", "FirstAttribute");
el.SetAttribute("Name", "SecondAttribute");
el.InnerText = ...;
Additional thoughts:
XElement
XmlSerializer (from a class instance)
If you’re on .NET 3.5 (or later), you could use LINQ to XML. Make sure that the System.Xml.Linq assembly is referenced, and that you have a using directive for its eponymous namespace.
XDocument document = new XDocument(
new XElement("ElementName",
new XAttribute("Type", "FirstAttribute"),
new XAttribute("Name", "SecondAttribute"),
value));
If you subsequently want to write the XDocument to a target, you can use its Save method. For debugging, it’s useful to call its ToString method, which returns its XML representation as a string.
Edit: Replying to comment:
If you need to convert the XDocument created above into an XmlDocument instance, you may use code similar to the following:
XmlDocument xmlDocument = new XmlDocument();
using (XmlReader xmlReader = document.CreateReader())
xmlDocument.Load(xmlReader);
What about using LINQ to XML as in this article. That can be very elegant - it can all be done on one line.
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("element",
new XAttribute("attribute1", "val1"),
new XAttribute("attribute2", "val2"),
)
);

.net webservice with XElement return type

There is a way to make a webservice that returns a parameter of the type XElement?
Now I'm working with XmlNode return type, but I want to get rid of using this old xml library.
I'm using this:
XDocument doc = new XDocument();
XElement xml = new XElement("produtos");
doc.Add(xml);
//...
var xmlDoc = new XmlDocument();
using (var xmlReader = doc.CreateReader())
{
xmlDoc.Load(xmlReader);
}
return xmlDoc;
I can't figure out why the webservice dont work with the XmlLinq lib
You should be able to do this:
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
public XElement GetSomething()
{
return new XElement("Something");
}
I used an extension method to convert the XElement to an XmlElement (per suggestion of #Ocelot20):
<System.Runtime.CompilerServices.Extension()> _
Public Function ToXmlElement(value As XElement) As XmlElement
Dim xmlDoc = New XmlDocument()
xmlDoc.LoadXml(value.ToString())
Return xmlDoc.DocumentElement
End Function
Seems to work fine!

How do I create an xmlElement from the current node of a xmlReader?

If I have an xmlreader instance how can I use it to read its current node and end up with a xmlElement instance?
Not tested, but how about via an XmlDocument:
XmlDocument doc = new XmlDocument();
doc.Load(reader);
XmlElement el = doc.DocumentElement;
Alternatively (from the cmoment), something like:
doc.LoadXml(reader.ReadOuterXml());
But actually I'm not a fan of that... it forces an additional xml-parse step (one of the more CPU-expensive operations) for no good reason. If the original is being glitchy, then perhaps consider a sub-reader:
using (XmlReader subReader = reader.ReadSubtree())
{
XmlDocument doc = new XmlDocument();
doc.Load(subReader);
XmlElement el = doc.DocumentElement;
}
Assuming that you have XmlDocument, where you need to attach the newly created XmlElement:
XmlElement myElement;
myXmlReader.Read();
if (myXmlReader.NodeType == XmlNodeType.Element)
{
myElement = doc.CreateElement(myXmlReader.Name);
myElement.InnerXml = myXmlReader.InnerXml;
}
From the docs: Do not instantiate an XmlElement directly; instead, use methods such as CreateElement.

Categories