1

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.

Chandramouli
  • 544
  • 6
  • 18
  • Can you please explain what problem are you trying to solve? Why would you want to extract the information from the config file using a custom class instead of using the `ConfigurationManager` class? – Rui Jarimba Oct 04 '18 at 08:58
  • Hello Chandramouli,can you give us more details about your problem? – Sambuu Oct 04 '18 at 09:00
  • Hi guys, this is not the actual web.config file. This is the Transform config which we will maintain in protected server(will not commit in Versioning tool). I would like to give an UI for the deployment team member to update these files. So we need to get this as list object. – Chandramouli Oct 04 '18 at 09:04
  • Mind to share serialization code which is not working? – Renatas M. Oct 04 '18 at 09:19

4 Answers4

2

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

Shmosi
  • 322
  • 2
  • 17
  • Here the problem is how to get the attribute values which are having namespaces(like xdt:Transform and xdt:Locator). – Chandramouli Oct 04 '18 at 09:06
  • I'm not sure what you are asking for, could you Point me to it? – Shmosi Oct 04 '18 at 09:07
  • In your logic, If i want to get the value of attributes xdt:Transform and xdt:Locator system will through an error called "object reference not set to an instance of an object" – Chandramouli Oct 04 '18 at 09:09
  • @Chandramouli I copied your XML and used it in my code. For the attributes tag I used `xdt:Transform` and got as a return-value for the first line `Replace` – Shmosi Oct 04 '18 at 09:22
  • Thank you, so much. it's working fine, actually i miss understood the solution that you are providing using the "XDocument" object. But on using the "XmlDocument" object it is working fine. Marked as answer. – Chandramouli Oct 04 '18 at 09:53
  • No probs, I had a hard time understanding/learning this myself :) – Shmosi Oct 04 '18 at 10:07
1

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
Renatas M.
  • 11,694
  • 1
  • 43
  • 62
0

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

Amit chauhan
  • 540
  • 9
  • 22
0

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

er-sho
  • 9,581
  • 2
  • 13
  • 26