C# convert dynamic string to xml with TAG

Asked

Viewed 153 times

0

I would like to know how to convert a string with XML inline to an XML with tags, I am using Xmldocument, I have the following code:

var MihaString="<MeuXML Info01="teste 0121245" Info02="2020-01-14" Info03="2019-12-30"/>";

the variable Mihastring is dynamic, I do not know what is the structure of XML, only I know it will come inline, and I always need to convert to XML with TAG

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(MihaString);
var result = xmlDocument.OuterXml;

However even using Outerxml it maintains the same input xml structure.

Expected result would be something like this:

<MeuXMLPai> 
 <MeuXML>
  <Info01> teste 0121245 </Info01>
  <Info02> 2020-01-14 </Info02>
  <Info03> 2019-12-30 </Info03>
 </MeuXML> 
</MeuXMLPai>
  • you besides one example have several others?

  • Any xml can come, for example: <Meuxml Info01="test 0121245" Info02="2020-01-14" Info03="2019-12-30"> <aaaa bbb="test 0121245" cccc="2020-01-14" ddd="2019-12-30"/> </Meuxml>, the goal is to take everything this inline and turn TAG

  • complicated, because it seems a more complicated operation than in the example. Usually this should already come ready, correctly, now you could write a text explaining the subject, if it is this way just make a recursive process and generate the nodes with the answer I gave you earlier

  • I managed to solve it, posted the answer here.

2 answers

1

There are several ways to do what you want, I have a project that handles xml strings directly, but in your case, you can use Xmldocument to do the required conversion.

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("seu xml");


XmlNode selectedNode = xmlDoc.SelectSingleNode("./<XPath>");
selectdeNode = changeNodeAttributesToElements(selectdeNode,xmlDoc);

private XmlNode changeNodeAttributesToElements(XmlNode node,XmlDocument xmlDoc)
{

    foreach (XmlAttribute att in node.Attributes)
    {
        XmlNode newNode = xmlDoc.CreateElement(att.Name);
        newNode.InnerText = att.Value;
        node.Append(newNode);
    }

node.Attributes.RemoveAll();
}

0

Using the reference of the answers 30166183 and 29426107, I adapted and managed to generate XML dynamically, converting the attributes to TAG.

Code:

Main

  XmlDocument document = new XmlDocument();
  document.LoadXml(stringXml);
  var dictionary = document.ToObject();
  var xmlElement = XmlDocumentExtension.ToXML(dictionary, document.LastChild.Name);
  var xmldoc = new XmlDocument();
  xmldoc.Load(xmlElement.CreateReader());
  var xmlResult = xmldoc.OuterXml;

Xmldocumentextension

  public static XElement ToXML(this IDictionary<string, object> dic, string firstNode)
  {
        IList<XElement> xElements = new List<XElement>();
        foreach (var item in dic)
        {
              xElements.Add(new XElement(item.Key.Contains("XX_XX") ? item.Key.Split(new string[] { "XX_XX" }, StringSplitOptions.None)[0] : item.Key, GetXElement(item.Value))); ;
        }
        XElement root = new XElement(firstNode, xElements.ToArray());
        return root;
  }

  private static object GetXElement(dynamic item)
  {
        if (item != null && item.GetType() != typeof(String))
        {
              IList<XElement> xElements = new List<XElement>();
              foreach (var item2 in item as IDictionary<string, object>)
              {
                    var dic = (item2.Value as IDictionary<string, object>);
                    var key = item2.Key;

                    if (item2.Key?.Contains("XX_XX") == true)
                    {
                          key = key.Split(new string[] { "XX_XX" }, StringSplitOptions.None)[0];
                    }          
                    
                    if (dic?.Keys.Count == 1 && dic.Keys.First() == "XXvalueXX")
                    {
                          xElements.Add(new XElement(key, GetXElement(dic.Values.First())));
                    }
                    else
                    {
                        xElements.Add(new XElement(key, GetXElement(item2.Value)));
                    }
              }
              return xElements.ToArray();
        }    
        return item;
  }

  public static IDictionary<string, object> ToObject(this XmlDocument document)
  {
        XmlElement root = document.DocumentElement;
        return ToObject(root, new ExpandoObject());
  }

  private static IDictionary<string, object> ToObject(XmlNode node, ExpandoObject config, int count = 1)
  {
        var parent = config as IDictionary<string, object>;
        foreach (XmlAttribute nodeAttribute in node.Attributes)
        {
              var nodeAttrName = nodeAttribute.Name.ToString();
              parent[nodeAttrName] = nodeAttribute.Value;
        }
        foreach (XmlNode nodeChild in node.ChildNodes)
        {
              if (IsTextOrCDataSection(nodeChild))
              {
                    parent["XXvalueXX"] = nodeChild.Value;
              }
              else
              {
                    string nodeChildName = nodeChild.Name.ToString();
                    if (parent.ContainsKey(nodeChildName))
                    {
                          parent[nodeChildName + "XX_XX" + count] = ToObject(nodeChild, new ExpandoObject(), count++);
                    }
                    else
                    {
                          parent[nodeChildName] = ToObject(nodeChild, new ExpandoObject());
                    }
              }
        }
        return config;
  }

  private static bool IsTextOrCDataSection(XmlNode node)
  {
        return node.Name == "#text" || node.Name == "#cdata-section";
  }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.