DynamicXMLNode C#
本文关键字:DynamicXMLNode | 更新日期: 2023-09-27 18:06:04
我想使用dynamicXMLNode从集合(List对象)生成xml文档。需要创建的XML具有重复的元素,如元素。在创建DynamicXMLNode时,不能创建该元素两次。它覆盖了前一个节点的值。下面显示一些代码。如有任何建议,我将不胜感激。
<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.
公共类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;
}
}
尝试XML Linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//<FileContents>
//<FileContent>
//<Metadata>
//<Country>UK</Country>
//<CounterPartyType>Legal</CounterPartyType>
//</Metadata>
//</FileContent>
//<FileContent>
//<Metadata>
//<Country>USA</Country>
//<CounterPartyType>Legal</CounterPartyType>
//</Metadata>
//</FileContent
XElement filecontents = new XElement("FileContents");
XElement filecontent = null;
XElement metadata = null;
filecontent = new XElement("FileContent");
filecontents.Add(filecontent);
metadata = new XElement("Metadata");
filecontent.Add(metadata);
metadata.Add(new XElement("Country","UK"));
metadata.Add(new XElement("CounterPartyType","Legal"));
filecontent = new XElement("FileContent");
filecontents.Add(filecontent);
metadata = new XElement("Metadata");
filecontent.Add(metadata);
metadata.Add(new XElement("Country", "USA"));
metadata.Add(new XElement("CounterPartyType", "Legal"));
}
}
}