2

アプリケーションの作業を節約する方法を提供したいと思っています。これは一種のプロジェクト機能です。プロジェクトはXMLにシリアル化する必要があります。DataContractSerializerがXMLを生成していますが、複数のプロジェクトがあり、次のことができる必要があるため、XMLファイル自体の完全なファイルを書き込むのではなく、シリアル化するXMLファイル内の場所を選択できる必要があります。これらのプロジェクトをProjectsXMLファイルから個別にデ/シリアル化します。

XMLに欲しいもの:

<Projects>
    <Project>
        <ID>...</ID>
        <Name>...</Name>
        <LastEdited>...</LastEdited>
        ...
    </Project>
    <Project>...</Project>
    <Project>...</Project>
</Projects>

次に、Linq to XMLを使用してプロジェクトIDに基づいてシリアル化および逆シリアル化し、ドキュメントをナビゲートします。

助言がありますか?よろしくお願いします。

4

1 に答える 1

1

これを行う方法を見つけました。それには問題がありますが、すべてを含めると、非常にスムーズに機能します。

XMLを生成するには:

DataContractSerializer ser = new DataContractSerializer(typeof(Project));
StringBuilder objectSB = new StringBuilder();
XmlWriter objectWriter = XmlWriter.Create(objectSB);
//I'm using this method in the object I want to serialize (hence the 'this')
ser.WriteObject(objectWriter, this);
objectWriter.Flush();

次に、StringBuilderをLinqtoXMLのXElementに変換できます。

Xelement xProject = Xelement.Parse(objectSB.ToString());

デシリアライズの場合:

DataContractSerializer ser = new DataContractSerializer(typeof(Project));
Project project = (CoilProject)ser.ReadObject(xProject.CreateReader());

逆シリアル化および再シリアル化せずに、LinqtoXMLを使用してXMLを編集することが数回あります。DataContractSerializerが追加する名前空間のため、これが必要になります。

//place this somewhere in your project's namespace
public static class MyExtensions
{
    public static IEnumerable<XElement> ElementsAnyNS(this XElement source, string localName)
    {
        return source.Elements().Where(e => e.Name.LocalName == localName);
    }

    public static XElement ElementAnyNS(this XElement source, string localName)
    {
        return source.Elements().Where(e => e.Name.LocalName == localName).Select(e => e).Single();
    }
}

これらの拡張メソッドを使用すると、名前空間を気にすることなく、シリアル化されたオブジェクトから1つまたは複数の要素を選択できます。これらの拡張メソッドを、LINQの名前空間を無視するというPavelMinaevの回答からXMLに適合させました。

于 2012-07-24T16:38:58.003 に答える