0

I have the following code:

  XNamespace testNM = "urn:lst-emp:emp";
                XDocument xDoc;
                string path = "project_data.xml";
                if (!File.Exists(path))
                {
                    xDoc = new XDocument(
                               new XDeclaration("1.0", "UTF-16", null),
                               new XElement(testNM + "Test")
                               );
                }
                else
                {
                    xDoc = XDocument.Load(path);
                }

                var element = new XElement("key",
                                        new XElement("Type", type),
                                        new XElement("Value", value));
                xDoc.Element(testNM + "Test").Add(element);

                // Save to Disk
                xDoc.Save(path);

which produces an output in the XML file like this:

<?xml version="1.0" encoding="utf-16"?>
<Test xmlns="urn:lst-emp:emp">
  <key xmlns="">
    <Type>String</Type>
    <Value>somestring</Value>
  </key>
</Test>

How can I get an output like this in the XML file instead?

<?xml version="1.0" encoding="utf-16"?>
<Tests xmlns="urn:lst-emp:emp">
  <key name="someString">
    <Type>String</Type>
    <Value>somestring</Value>
  </key >
</Tests>

Note its only the 3rd line that has changed in the XML file.

2
  • 1
    Well, you need a name attribute, and you presumably need your element to be in the default namespace in your context - which we can't tell because you've only shown that element rather than the wider document of which it's a part. Those are two different issues - what have you tried for each of them? Commented Aug 21, 2014 at 8:10
  • My code has been edited. Check it above! Commented Aug 21, 2014 at 8:15

3 Answers 3

3

You can do it this way:

var element = new XElement("key",
                           new XAttribute("name", "someString"),
                           new XElement("Type", "type"),
                           new XElement("Value", "value"));
Sign up to request clarification or add additional context in comments.

4 Comments

Don't forget about the mismatched namespace. The fact that the OP's code outputted an explicit xmlns="" that wasn't desired in the output means that he needs to specify the namespace to be whatever its parent is. So yes, but that should be noted. He'll (probably) want to say ...new XElement(XName.Get("key", someString), ....
I updated the question with the entire code. Pls take a look!
You can remove all the namespaces using this approach: stackoverflow.com/questions/987135/…
Thanks! Your code works perfectly. Also, how can I access the attribute 'name'? currentElement.Name.LocalName is what I used previously.
2

To provide a complete version of Bilyukov's answer, this should produce the output expected. Obviously substitute the "someString" static string with a variable populated as you wish. Changes include using XName.Get(string, string) to create the appropriate XName objects for the XElement constructors.

 XNamespace testNM = "urn:lst-emp:emp";
            XDocument xDoc;
            string path = "project_data.xml";
            if (!File.Exists(path))
            {
                xDoc = new XDocument(
                           new XDeclaration("1.0", "UTF-16", null),
                           new XElement(XName.Get("Tests", testNM.NamespaceName))
                           );
            }
            else
            {
                xDoc = XDocument.Load(path);
            }

            var element = new XElement(XName.Get("key", testNM.NamespaceName),
                                    new XAttribute("name", "someString"),
                                    new XElement("Type", type),
                                    new XElement("Value", value));
            xDoc.Element(XName.Get("Tests", testNM.NamespaceName)).Add(element);

            // Save to Disk
            xDoc.Save(path);

8 Comments

Thanks, this is great! If I wanted to access an element based on the 'name' attribute (eg: element with key name=abc), how would I do that?
Also, your code has some errors. XName.Get() has some invalid arguments.
Probably best to ask that as a separate question but offhand - xDoc.Element(XName.Get("Tests", testNM)).Elements(XName.Get("key", testNM)).Where(x => x.Attribute("name") != null && x.Attribute("name").Value == "abc").Single()
Thanks, I'll work on that. XName.Get() still has some invalid arguments in the code above though.
|
1

Your XML has default namespace. Descendants of the element where default namespace declared is considered in the same default namespace, unless it is explicitly declared with different namespace. That's why you need to use the same XNamespace for <key> element. :

var element = new XElement(testNM +"key",
                           new XAttribute("name", "someString"),
                           new XElement(testNM +"Type", type),
                           new XElement(testNM +"Value", value));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.