Reading the XML with namespaces at attribute level using c#

268 Views Asked by At

I have an XML file like following

<?xml version="1.0"?>
<appSettings xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <add xdt:Transform="Replace" xdt:Locator="Match(key)" key="Key1" value="TransformValue1"/>
  <add xdt:Transform="Replace" xdt:Locator="Match(key)" key="Key2" value="TransformValue2"/>
  <add xdt:Transform="Replace" xdt:Locator="Match(key)" key="Key3" value="TransformValue3"/>
  <add xdt:Transform="Replace" xdt:Locator="Match(key)" key="Key4" value="TransformValue4"/>

  <add xdt:Transform="Insert" key="Key6" value="TransformValue6"/>
</appSettings>

I want to get this XML as List of class Key. here the Key class is as follows

[Serializable]
public class Key
{
    public string Key { get; set; }
    public string Value { get; set; }
    public string Transform { get; set; }
    public string Locator { get; set; }
}

Please suggest

Hi all, for better understanding of my problem i'm updating the question with purpose.

Purpose: As part of automatic deployments, we are planning to automate the deployment of web.config file also. To achieve this process we are using the concept of "Web config transform". To achieve this "Web config transform", we will maintain the transform files(for all instances and clients) in centralized server and these will be used for transform. But to update the transform file we are giving the Ui for the deployment team member. For this we need to read the XML config with name spaces.

4

There are 4 best solutions below

0
On BEST ANSWER

If you create models to hold your data, then you can easily deserialize object from file with 2 lines of code:

public class appSettings
{
    [XmlElement("add")]
    public List<Item> AddItems { get; set; }
}

public class Item
{
    [XmlAttribute("key")]
    public string Key { get; set; }
    [XmlAttribute("value")]
    public string Value { get; set; }
    [XmlAttribute(Namespace="http://schemas.microsoft.com/XML-Document-Transform")]
    public string Transform { get; set; }
    [XmlAttribute(Namespace="http://schemas.microsoft.com/XML-Document-Transform")]
    public string Locator { get; set; }
}

XmlSerializer ser = new XmlSerializer(typeof(appSettings));
var settings = (appSettings)ser.Deserialize(File.Open("test.xml", FileMode.Open));
settings.AddItems; //<- there is your list
1
On

I want to get this XML as List of class Key.

Here i create an console app for your demonstration purpose.

By below code you can get list of your elements add inside appSettings into your Key class from your xml.

class Program
    {
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(@"Your xml here");
            XNamespace ns = doc.Root.GetDefaultNamespace();
            XNamespace xdt = "http://schemas.microsoft.com/XML-Document-Transform";

            var result = doc.Descendants(ns + "appSettings")
                .Elements(ns + "add")
                         .Select(x => new Key
                         {
                             Key1 = x.Attribute(xdt + "Transform") != null ? x.Attribute(xdt + "Transform").Value : "",
                             Value = x.Attribute(xdt + "Locator") != null ? x.Attribute(xdt + "Locator").Value : "",
                             Transform = x.Attribute("key") != null ? x.Attribute("key").Value : "",
                             Locator = x.Attribute("value") != null ? x.Attribute("value").Value : "",
                         }).ToList();


            result.ForEach(x => Console.WriteLine($"Transform: {x.Transform}, \t Locator: {x.Locator}, \t Key: {x.Key1}, \t Value: {x.Value}"));

            Console.ReadLine();
        }
    }



[Serializable]
    public class Key
    {
        public string Key1 { get; set; }
        public string Value { get; set; }
        public string Transform { get; set; }
        public string Locator { get; set; }
    }

Output:

enter image description here

6
On

I would ise XmlDocument for this approach. One reason is, that you can simply choose all tags (in your case add) that you want to use. Second, with a foreach Loop you can easily obtain all values via the Attributes call

XmlDocument xdoc = new XmlDocument();

xdoc.LoadXml("YourXmlString");

XmlNodeList xNodes = xdoc.GetElementsByTagName("add");


foreach(XmlNode item in xNodes)
{    
    key = item.Attributes["state"].Value;

    //and so on
}

I hope I could solve your problem

0
On

Have you tried using XPathSelectElements method of XElement class in this we can provide the xpath to get the value

ex-

doc.XPathSelectElements("//add[@xdt:Transform!=text() or not(@xdt:Transform)]", doc.Root.CreateNavigator());

I have found this answer from this post read from here