Reputation: 1369
My Goal is create an XML node
that has two attributes
- one is a namespace
and another is a prefix
of that namespace
, as shown below:
So far I have tried 3 options:
Option 1: Hardcoding it, does not work.
XElement paymentmethodType = XElement.Parse("<PaymentMethod xmlns:xsi=\"w3.org/2001/XMLSchema-instance\" xsi:type=\"CreditTransferType\"/>");
I only get this:
<PaymentMethod xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" type="CreditTransferType">
Option 2 : Using my structure with XmlAttributes and XMlNodes:
XmlAttribute paymentmethodNamespace = CreateAttribute(paymentMethod, "xmlns:xsi", "http://w3.org/2001/XMLSchema-instance");
XmlAttribute paymentmethodType = CreateAttribute(paymentMethod, "xsi:type", "CreditTransferType");
public XmlAttribute CreateAttribute(XmlNode parentNode, string attributeName, string attributeValue)
{
var attribute = parentNode.OwnerDocument.CreateAttribute(attributeName);
attribute.Value = attributeValue;
parentNode.Attributes.Append(attribute);
// parentNode.AppendChild(node);
return attribute;
}
I again get this:
<PaymentMethod xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" type="CreditTransferType">
Option 3 : XElement and XAttributes:
XElement paymentMethod = new XElement("PaymentMethod",
new XAttribute(XNamespace.Xmlns + "xsi", "http://w3.org/2001/XMLSchema-instance"),
new XAttribute(XNamespace.Xmlns + "xsi:type", "CreditTransferType"));
But i get an Exception
that ":" is not a valid symbol. Also it is a problem because I use XMlDocument
and it only works with XMlNode
and XMlAttribute
. It does not work with XAttribute
.
Now I have over 400 lines of codes and I just want to set this namespace and I am done with the doc. Is there an easy way of doing it?
Upvotes: 1
Views: 595
Reputation: 34421
The following works :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
string xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><root></root>";
XDocument doc = XDocument.Parse(xmlHeader);
XElement root = doc.Root;
XElement paymentmethodType = XElement.Parse("<PaymentMethod xmlns:xsi=\"w3.org/2001/XMLSchema-instance\" xsi:type=\"CreditTransferType\"/>");
root.Add(paymentmethodType);
doc.Save(FILENAME);
}
}
}
Upvotes: 1
Reputation: 1369
So I used option 3 as dim suggested.
What I did so I do not have to rewrite the whole lot was to create a second document that loads the XML.
Then the first doc imports the node from the second doc and appends it to the root element and it works fine.
XmlDocument doc2 = new XmlDocument();
XNamespace ns = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
XElement paymentMethodEl = new XElement("PaymentMethod",
new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
new XAttribute(ns + "type", "CreditTransferType"));
doc2.LoadXml(paymentMethodEl.ToString());
XmlWriter writer2 = XmlWriter.Create(Path.Combine(Settings.Default.InvoiceXmlFolder, "doc2.xml"), settings);
doc2.Save(writer2);
XmlNode paymentMethod = doc.ImportNode(doc2.FirstChild, true);
rootNode.AppendChild(paymentMethod);
Upvotes: 0
Reputation: 45
I don't know about Option 1
and Option 2
but for Option 3
- What you have to do is Get the namespace
first, then use the namespace
to assign type
. Because that namespace is xmlns:xsi
, you assign it type it will automatically match to xsi:type
. In short here is the code:
XNamespace ns = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
new XElement("PaymentMethod",
new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
new XAttribute(ns + "type", "CreditTransferType"));
Upvotes: 1