1

ここでのKevinHazzardの投稿に基づいています。http://blogs.captechconsulting.com/blog/kevin-hazzard/fluent-xml-parsing-using-cs-dynamic-type-part-1 ロジックを使用しようとしています。基本的に、これが行うことになっているのは、XMLの一部を取得し、それを使用可能なオブジェクトに変換することです。たとえば、私のxmlは;

<someObject>
    <Name>Timmy</Name>
</someObject>

できるようになりたいです。

dynamic obj = Converter(xmlText);
string name obj.Name;

グーグルを何度も行った後、私はケビンのブログに出くわし、DynamicXmlその仕事をするはずのオブジェクトを投稿しましたが、それを機能させることができません(または正しく使用していません)。.NETのExpandoオブジェクトについての私の理解は限られており、ブログ投稿を禁止するためのコードサンプルはありません。私はこの主題に関するケビンの2つの投稿を1つのオブジェクトにまとめました。

public class DynamicXml : DynamicObject, IEnumerable
{
    private readonly List<XElement> _elements;

    public DynamicXml(string text)
    {
        var doc = XDocument.Parse(text);
        _elements = new List<XElement> { doc.Root };
    }

    protected DynamicXml(XElement element)
    {
        _elements = new List<XElement> { element };
    }

    protected DynamicXml(IEnumerable<XElement> elements)
    {
        _elements = new List<XElement>(elements);
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = null;

        // handle the Value and Count special cases
        if (binder.Name == "Value")
        {
            result = _elements[0].Value;
        }
        else if (binder.Name == "Count")
        {
            result = _elements.Count;
        }
        else
        {
            // try to find a named attribute first
            var attr = _elements[0].Attribute(XName.Get(binder.Name));
            if (attr != null)
            {
                // if a named attribute was found, return that NON-dynamic object
                result = attr;
            }
            else
            {
                // find the named descendants 
                var items = _elements.Descendants(
                    XName.Get(binder.Name));
                if (items != null && items.Count() > 0)
                {
                    // prepare a new dynamic object with the list of found descendants
                    result = new DynamicXml(items);
                }
            }
        }

        if (result == null)
        {
            // not found, create a new element here 
            _elements[0].AddFirst(new XElement(binder.Name));
            result = new DynamicXml(_elements[0].Descendants().First());
        }
        return true;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (binder.Name == "Value")
        {
            /* the Value property is the only one that may be modified. TryGetMember actually
                creates new XML elements in this implementation */
            _elements[0].Value = value.ToString();
            return true;
        }
        return false;
    }

    public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
    {
        int ndx = (int)indexes[0];
        result = new DynamicXml(_elements[ndx]);
        return true;
    }

    public IEnumerator GetEnumerator()
    {
        foreach (var element in _elements)
            yield return new DynamicXml(element);
    }
}

私の使用法は;

dynamic payload = new DynamicXml(PayloadData);
Name = payload.Name;    // error thrown here

例外は次のとおりです。

Cannot implicitly convert type 'MyProject.Common.Exchange.DynamicXml' to 'string'

オブジェクトを調べると、それはネストされた一連のDynamicXml-のように見えます。これは、コードの内部を見ると正しいように見えます。だから私は実際にどのように価値を得るのか疑問に思っていますNameか?ブログによると、それはただのはずpayload.Nameです。考え?

4

1 に答える 1

5

非常に重要なことを1つ見逃しました。ノードを名前で呼び出すことはできますが、getMemberは常にDynamicXmlオブジェクトを返すため、その値を参照解除する必要があります。

試す:

payload.Name.Value
于 2013-03-06T21:51:24.367 に答える