3

C#クラス構造をXMLにシリアル化し、ネストされたクラスの束を持たずに特定のノード名を提供したいと思います。属性を使用してそれは可能ですか?

たとえば、次のXMLがあるとします。

<OuterItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <InnerItem>
        <ItemValue>something i need</ItemValue>
    </InnerItem>
</OuterItem>

次のようなXMLシリアル化メソッドがあります。

public static string XmlSerializeToString<T>(T value)
{
    if (value == null) { return null; }

    XmlSerializer serializer = new XmlSerializer(typeof(T));

    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = false;
    settings.OmitXmlDeclaration = true;

    using (StringWriter textWriter = new StringWriter())
    using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
    {
        serializer.Serialize(xmlWriter, value);
        return textWriter.ToString();
    }
}

このようなC#クラス構造が必要ですか?

public class OuterItem
{
    public InnerItem InnerItem { get; set; }
}

public class InnerItem
{
    public string ItemValue { get; set; }
}

または、次のようなもの(擬似コード)を使用して、XMLドキュメントのどこまでノードを配置する必要があるかを宣言することは可能ですか?

public class OuterItem
{
    [XmlNode("InnerItem\ItemValue")]
    public string ItemValue { get; set; }
}
4

1 に答える 1

0

いいえ、XmlNode属性でxpathまたは同様の式を使用することはできません。xmlシリアル化を制御するための属性の選択は非常に限られています。

次のハックを使用して、使用しているxmlを逆シリアル化できます。

public class OuterItem
{
    [XmlArrayItem(ElementName="ItemValue", Type=typeof(string))]
    [XmlArray]
    public string[] InnerItem
    {
        get; set;
    }
}

public class Test
{
    static void Main()
    {
        var item = new OuterItem { InnerItem = new[]{"AAA"} };
        XmlSerializer ser = new XmlSerializer(typeof(OuterItem));
        ser.Serialize(Console.Out,item);
    }
}

これにより、次のxmlが生成されます。

<?xml version="1.0" encoding="utf-8"?>
<OuterItem xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <InnerItem>
    <ItemValue>AAA</ItemValue>
  </InnerItem>
</OuterItem>

もう1つの可能な解決策は、XmlTextAttributeを使用し、内部xmlをXmlNodeタイプのプロパティに取得して、手動で解析することです。

于 2013-04-16T21:36:29.110 に答える