Eleanor
Eleanor

Reputation: 569

Replace xml value with c#

I have a xml and I want to rewrite it with c#, to transfrom it with different vaule, here is the old xml:

    <Connection ConnectionID="106359" From_PhraseID="1" To_PhraseID="tg1c8p-jgg-dbh-b4l-hir5cpla7_nl" />
    <Connection ConnectionID="106360" From_PhraseID="tg1c8p-jgg-dbh-b4l-hir5cpla7_nl" To_PhraseID="tg0if2-jc8-k6i-spg-2tof46ftr_nl" />
    <Connection ConnectionID="106361" From_PhraseID="tg1c8p-jgg-dbh-b4l-hir5cpla7_nl" To_PhraseID="4trq50-2h0-kqc-9ku-bm8f4cte7_nl" />
    <Connection ConnectionID="106362" From_PhraseID="tg1c8p-jgg-dbh-b4l-hir5cpla7_nl" To_PhraseID="1fpspg-tmq-7ln-a9b-3mr3962ca_nl" />
    <Connection ConnectionID="106358" From_PhraseID="tg0if2-jc8-k6i-spg-2tof46ftr_nl" To_PhraseID="jmrgi1-dst-kt6-roo-lrahuk6tj_nl" />
    <Connection ConnectionID="106373" From_PhraseID="4trq50-2h0-kqc-9ku-bm8f4cte7_nl" To_PhraseID="97bngg-ggb-k8l-ggf-qnre46ckq_nl" />
    <Connection ConnectionID="106376" From_PhraseID="1fpspg-tmq-7ln-a9b-3mr3962ca_nl" To_PhraseID="bqgccm-55n-iur-061-27obhegve_nl" />

and The new xml supposed to be :

<Connection ConnectionID="106359" From_PhraseID="0" To_PhraseID="1" />
<Connection ConnectionID="106360" From_PhraseID="1" To_PhraseID="2" />
<Connection ConnectionID="106361" From_PhraseID="1" To_PhraseID="3" />
<Connection ConnectionID="106362" From_PhraseID="1" To_PhraseID="4" />
<Connection ConnectionID="106358" From_PhraseID="2" To_PhraseID="6" />
<Connection ConnectionID="106373" From_PhraseID="3" To_PhraseID="7" />
<Connection ConnectionID="106376" From_PhraseID="4" To_PhraseID="5" />

any idea how to write it in c#, I have a start at here, this code can load the old xml get all the old value in c#, but how to change the value

     public class Dialogs{
            public Dictionary<string, Connection> Connections = new Dictionary<string, Connection>();
        }
    public class Connection
    {
        public string ConnectionID = null;
        public string FromPhraseID = null;
        public string ToPhraseID = null;
    }
    List<Connection> connectionsList = new List<Connection>();
            Dialogs resultDialog = new Dialogs();

            // Document

            XmlDocument xml = new XmlDocument();
            TextAsset asset = (TextAsset)Resources.Load("Dialogs/online"); 
            xml.LoadXml(asset.text);
// Connections

        XmlNodeList connections = xml.GetElementsByTagName("Connection");

        foreach (XmlNode connectionNode in connections)
        {
            Connection connection = NodeToConnection(connectionNode);
            connectionsList.Add(connection);

            if (connection != null)
            AddOrUpdateList(resultDialog.FromLists, connection);

        }
private Connection NodeToConnection(XmlNode node)
    {
        Connection connection = new Connection();

        connection.ConnectionID = node.Attributes["ConnectionID"].Value;
        connection.FromPhraseID = node.Attributes["From_PhraseID"].Value;
        connection.ToPhraseID = node.Attributes["To_PhraseID"].Value;

        return connection;
    }

    private void AddOrUpdateList(Dictionary<string, List<Connection>> dic, Connection con)
    {
        if (dic.ContainsKey(con.FromPhraseID))
            dic[con.FromPhraseID].Add(con);
        else        
            dic.Add(con.FromPhraseID, new List<Connection>(new Connection[] {con}));        
    }

Upvotes: 0

Views: 601

Answers (3)

JJJCoder
JJJCoder

Reputation: 16916

I use LINQ to XML.

Here is a sample that will do what you want for one element. I will let you take it from there.

static void Main(string[] args)
        {
            try
            {
                string rootXml = "<Root><Connection ConnectionID=\"106359\" From_PhraseID=\"1\" To_PhraseID=\"tg1c8p-jgg-dbh-b4l-hir5cpla7_nl\"></Connection><Connection ConnectionID=\"106360\" From_PhraseID=\"tg1c8p-jgg-dbh-b4l-hir5cpla7_nl\" To_PhraseID=\"tg0if2-jc8-k6i-spg-2tof46ftr_nl\"></Connection><Connection ConnectionID=\"106361\" From_PhraseID=\"tg1c8p-jgg-dbh-b4l-hir5cpla7_nl\" To_PhraseID=\"4trq50-2h0-kqc-9ku-bm8f4cte7_nl\"></Connection><Connection ConnectionID=\"106362\" From_PhraseID=\"tg1c8p-jgg-dbh-b4l-hir5cpla7_nl\" To_PhraseID=\"1fpspg-tmq-7ln-a9b-3mr3962ca_nl\"></Connection><Connection ConnectionID=\"106358\" From_PhraseID=\"tg0if2-jc8-k6i-spg-2tof46ftr_nl\" To_PhraseID=\"jmrgi1-dst-kt6-roo-lrahuk6tj_nl\"></Connection><Connection ConnectionID=\"106373\" From_PhraseID=\"4trq50-2h0-kqc-9ku-bm8f4cte7_nl\" To_PhraseID=\"97bngg-ggb-k8l-ggf-qnre46ckq_nl\"></Connection><Connection ConnectionID=\"106376\" From_PhraseID=\"1fpspg-tmq-7ln-a9b-3mr3962ca_nl\" To_PhraseID=\"bqgccm-55n-iur-061-27obhegve_nl\"></Connection></Root>";

                XElement root = XElement.Load((new StringReader(rootXml)), LoadOptions.None);

                root.Descendants().Where(i => i.Attribute("To_PhraseID").Value == "tg1c8p-jgg-dbh-b4l-hir5cpla7_nl")
                                    .ToList()
                                    .ForEach(i => i.SetAttributeValue("To_PhraseID", "MYNEWID"));

                var x = root.ToString();
            }
            catch (Exception ex)
            {

            }
        }

Upvotes: 0

Charles Mager
Charles Mager

Reputation: 26213

Use the property setter?

You're getting the value by node.Attributes["ConnectionID"].Value, so you can set it by:

node.Attributes["ConnectionID"].Value = "new value"

I'd strongly suggest using LINQ to XML (XDocument) rather than the old XmlDocument API if you can.

In this case it may even make more sense (and use far less code) to use XmlSerializer to deserialize your XML to Connection objects, make the changes, and serialize back to XML.

It's not clear what your renumbering logic is. I've created an example doing this with LINQ to XML and number the Phrase IDs in the order they are seen:

public class ConnectionRenumberer
{
    private List<string> phraseIds;

    public string RenumberConnections(string xml)
    {
        phraseIds = new List<string>();

        var doc = XDocument.Parse(xml);

        foreach (var connection in doc.Descendants("Connection"))
        {
            var from = connection.Attribute("From_PhraseID");
            from.Value = NewPhraseId(from.Value);

            var to = connection.Attribute("To_PhraseID");
            to.Value = NewPhraseId(to.Value);                    
        }

        return doc.ToString();
    }

    private string NewPhraseId(string value)
    {
        var index = phraseIds.IndexOf(value);

        if (index == -1)
        {
            index = phraseIds.Count;
            phraseIds.Add(value);
        }

        return index.ToString();
    }
}

This is a fairly naive solution. phraseIds would be better replaced with, say, a Dictionary if the input xml is large.

Upvotes: 0

jdweng
jdweng

Reputation: 34421

Try code below. I used a dictionary to store replacement values

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication28
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
                "<Connection ConnectionID=\"106359\" From_PhraseID=\"1\" To_PhraseID=\"tg1c8p-jgg-dbh-b4l-hir5cpla7_nl\" />" +
                "<Connection ConnectionID=\"106360\" From_PhraseID=\"tg1c8p-jgg-dbh-b4l-hir5cpla7_nl\" To_PhraseID=\"tg0if2-jc8-k6i-spg-2tof46ftr_nl\" />" +
                "<Connection ConnectionID=\"106361\" From_PhraseID=\"tg1c8p-jgg-dbh-b4l-hir5cpla7_nl\" To_PhraseID=\"4trq50-2h0-kqc-9ku-bm8f4cte7_nl\" />" +
                "<Connection ConnectionID=\"106362\" From_PhraseID=\"tg1c8p-jgg-dbh-b4l-hir5cpla7_nl\" To_PhraseID=\"1fpspg-tmq-7ln-a9b-3mr3962ca_nl\" />" +
                "<Connection ConnectionID=\"106358\" From_PhraseID=\"tg0if2-jc8-k6i-spg-2tof46ftr_nl\" To_PhraseID=\"jmrgi1-dst-kt6-roo-lrahuk6tj_nl\" />" +
                "<Connection ConnectionID=\"106373\" From_PhraseID=\"4trq50-2h0-kqc-9ku-bm8f4cte7_nl\" To_PhraseID=\"97bngg-ggb-k8l-ggf-qnre46ckq_nl\" />" +
                "<Connection ConnectionID=\"106376\" From_PhraseID=\"1fpspg-tmq-7ln-a9b-3mr3962ca_nl\" To_PhraseID=\"bqgccm-55n-iur-061-27obhegve_nl\" />";

            input = "<Root>" + input + "</Root>";
            StringReader reader = new StringReader(input);
            XDocument doc = XDocument.Load(reader);

            int value = 1;
            Dictionary<string, int> dict = new Dictionary<string, int>();
            foreach (XElement connection in doc.Root.Elements("Connection"))
            {
                string fromAttr = connection.Attribute("From_PhraseID").Value;
                if (!dict.ContainsKey(fromAttr))
                {
                    dict.Add(fromAttr, value++);
                }
                string toAttr = connection.Attribute("To_PhraseID").Value;
                if (!dict.ContainsKey(toAttr))
                {
                    dict.Add(toAttr, value++);
                }
            }
            foreach (XElement connection in doc.Root.Elements("Connection"))
            {
                string fromAttr = connection.Attribute("From_PhraseID").Value;
                connection.Attribute("From_PhraseID").Value = dict[fromAttr].ToString();
                string toAttr = connection.Attribute("To_PhraseID").Value;
                connection.Attribute("To_PhraseID").Value = dict[toAttr].ToString();
            }
        }
    }
}

Upvotes: 1

Related Questions