samedi 1 août 2015

DynamicXMLNode C#

i am tempted to use dynamicXMLNode for xml document generation from a collection(List objects). the xml that needs to be created has repeating elements like the element . When creating a DynamicXMLNode I cannot create the element twice. It is overriding the values of the previous node. Some code appears below. Any advice would be most appreciated.

<FileContents>
<FileContent>
<Metadata>
<Country>UK</Country>
<CounterPartyType>Legal</CounterPartyType>
</Metadata>
</FileContent>
<FileContent>
<Metadata>
<Country>USA</Country>
<CounterPartyType>Legal</CounterPartyType>
</Metadata>
</FileContent>

//Node 1
dynamic topNode = new DynamicXMLNode("FileContents");
topNode.FileContent = new DynamicXMLNode("FileContent");
topNode.FileContent.Metadata = new DynamicXMLNode("MetaData");
topNode.FileContent.Metadata.Country= "UK";
topNode.FileContent.Metadata.CounterpartyType= "Legal";

//Node 2
topNode.FileContent = new DynamicXMLNode("FileContent1");
topNode.FileContent.Metadata = new DynamicXMLNode("MetaData1");
//This is overriding the values set in the prev node. However if I do 
topNode.FileContent1 then my xml element is named as FileContent1 which is not what I want. I beleieve this must be something I need to tweak in the DynamicXMLNode class. 

public class DynamicXMLNode : DynamicObject { XElement _node;

    public DynamicXMLNode(XElement node)
    {
        this._node = node;
    }

    public DynamicXMLNode(string name)
    {
        _node = new XElement(name);
    }

    public static DynamicXMLNode Parse(string text)
    {
        return new DynamicXMLNode(XElement.Parse(text));
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        Type xmlType = typeof(XElement);
        try
        {                
            List<object> newargs = null;
            var argtypes = args.Select(x => x.GetType()); 
            if (argtypes.Contains(typeof(DynamicXMLNode)) || argtypes.Contains(typeof(DynamicXMLNode[])))
            {
                newargs = new List<object>();
                foreach (var arg in args)
                {
                    if (arg.GetType() == typeof(DynamicXMLNode))
                    {
                        newargs.Add(((DynamicXMLNode)arg)._node);
                    }
                    else if (arg.GetType() == typeof(DynamicXMLNode[]))
                    {                           
                        newargs.Add(((DynamicXMLNode[])arg).Select(x => (x)._node));
                    }
                    else
                    {
                        newargs.Add(arg);
                    }
                }
            }

            result = xmlType.InvokeMember(
                      binder.Name,
                      BindingFlags.InvokeMethod |
                      BindingFlags.Public |
                      BindingFlags.Instance,
                      null, _node, newargs == null ? args : newargs.ToArray());

            if (result != null && typeof(IEnumerable<XElement>).IsAssignableFrom(result.GetType()))
            {
                result = ((IEnumerable<XElement>)result).Select(x => new DynamicXMLNode(x));
            }

            return true;
        }
        catch
        {
            result = null;
            return false;
        }
    }



    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        XElement setNode = _node.Element(binder.Name);
        if (setNode != null)
            setNode.SetValue(value);
        else
        {
            if (value.GetType() == typeof(DynamicXMLNode))
                _node.Add(new XElement(binder.Name));
            else
                _node.Add(new XElement(binder.Name, value));
        }
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        XElement getNode = _node.Element(binder.Name);
        if (getNode != null)
        {
            result = new DynamicXMLNode(getNode);
            return true;
        }
        else
        {
            result = null;
            return false;
        }
    }

    public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
    {

        string name = (string)indexes[0];
        result = _node.Attribute(name); //maybe check for null here
        return true;
    }

    public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
    {
        string name = (string)indexes[0];
        _node.SetAttributeValue(name, value);
        return true;
    }

}

Aucun commentaire:

Enregistrer un commentaire