0

XML ファイルをリピーターにバインドし、テキスト ボックス内の各項目をバインドしています。保存アクションがトリガーされたら、変更を XML ファイルに書き戻す必要があります。私の質問は、XML ファイルが非常に小さいことを念頭に置いて、これを行う最も効率的な方法は何かということです。

考えられるのは 3 つですが、どれが最適かはわかりません。

  1. リピーターをループし、XML ファイルで一致する ID を見つけ、それらのノードを更新します。
  2. XML ファイルをループし、リピーターで一致する ID を見つけ、それらのノードを更新します。
  3. 新しい XML ファイルを作成します (古いものを置き換えます)。

ありがとう!

私のXMLファイルがどのように見えるかのサンプルで更新されました:

<?xml version="1.0" encoding="UTF-8"?>
<Link>
<LinkNode>
<Section>New York</Section>
<Header>New York</Header>
<Item>IT/ Phone Support</Item>
<Details>Ext 5.8115</Details>
<ID>0</ID>
<HyperLink>0</HyperLink>
</LinkNode>
<LinkNode>
<Section>New York</Section>
<Header />
<Item>Email</Item>
<Details>info@gld.com</Details>
<ID>1</ID>
<HyperLink>2</HyperLink>
</LinkNode>
</Link>

そして、ここに私のクラスがあります:

public class Link
{
    public String Section { get; set; }
    public String Header { get; set; }
    public String Item { get; set; }
    public String Details { get; set; }
    public Int32 ID { get; set; }
    public Int32 Hyperlink { get; set; }
}

My Links コンストラクター:

 var LinksList = new List<Links>();
 var query = links_xml.Root.Descendants("LinkNode").Select(d => d);

            foreach (var q in query)
            {



                var linklist = new Links((!string.IsNullOrEmpty(q.Element("Header").Value)) ? q.Element("Header").Value : "",
                    (!string.IsNullOrEmpty(q.Element("Item").Value)) ? q.Element("Item").Value : "",
                    (!string.IsNullOrEmpty(q.Element("Details").Value)) ? q.Element("Details").Value : "",
                    (int)q.Element("ID"), (int)q.Element("HyperLink"));
                LinksList.Add(linklist);

            }
4

2 に答える 2

1

必要なプロパティを含むクラスオブジェクトを作成することもできます。XMLの読み取りと書き込みをDAL層に配置します。このようにして、DALList<Url>はこれらのオブジェクトの1つを送受信し、アプリケーションの残りの部分からデータアクセス(この場合はXML)を抽象化します。

データストレージ方式を(SQLなどに)変更することを選択した場合は、DAL方式を変更するだけで済み、残りのコードは影響を受けません。

いくつかのコードを説明したい場合はお知らせください。

編集:(いくつかのコード)

要素に次のプロパティがあるとすると、これはクラスになります。

public class Url
{
     public int Id {get; set;}
     public string DisplayName {get; set;}
     public string Url {get; set;}
}

その場合、DALクラスは次のようになります。

/// <summary>
/// Handles data access for Url entities
/// </summary>
public static class UrlDAL
{
    /// <summary>
    /// The path where the file resides
    /// </summary>
    const string __FilePath = @"~\App_Data\";
    /// <summary>
    /// The name of the file
    /// </summary>
    const string __FileName = "UrlList.xml";
    /// <summary>
    /// The name of the temporary file. Used to keep a copy of the file if saving the new file fails.
    /// </summary>
    const string __FileNameTemp = "UrlList_TEMP.xml";

    /// <summary>
    /// Retrieves a list of url entity objects
    /// </summary>
    /// <returns></returns>
    internal static List<Url> Retrieve()
    {
        List<Url> urls = null;

        try
        {
            //read xml file
            XDocument data  = XDocument.Load(HttpContext.Current.Server.MapPath(Path.Combine(UrlDAL.__FilePath, UrlDAL..__FileName)));
            //convert to list
            urls = Xml.DeserializeCollection<Url>(data);
        }
        catch (Exception e)
        {
            //perform logging / error handling
        }

        return urls;

    }

    /// <summary>
    /// Saves the list of Url entities 
    /// </summary>
    /// <param name="urls">The list of url objects to save</param>
    internal static void Create(List<Url> urls)
    {

        try
        {
            //convert list into xml document
            XDocument file = Xml.SerializeCollection<Url>(urls);
            //rename the old file so you have a copy of it if saving the new file fails
            File.Copy(Path.Combine(UrlDAL.__FilePath, UrlDAL.__FileName), Path.Combine(UrlDAL.__FilePath, UrlDAL.__FileNameTemp));
            //saving the new file will overwrite the existing file
            file.Save(UrlDAL.__FilePath);
            //delete the old file
            File.Delete(Path.Combine(UrlDAL.__FilePath, UrlDAL.__FileNameTemp));
        }
        catch (Exception e)
        {
            //perform logging / error handling
            //you should also alert yourself of this error so you can manually restore the old file
        }

    }

}

XMLのシリアル化/逆シリアル化に使用される拡張メソッドは次のとおりです。

public static class Xml
{
    /// <summary>
    /// Converts an XDoc into a List<T> of entities
    /// </summary>
    /// <typeparam name="T">Any serializable object</typeparam>
    /// <param name="doc"></param>
    /// <returns></returns>
    public static List<T> DeserializeCollection<T>(XDocument doc)
    {
        if (doc == null)
            return null;

        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
            XmlReader reader = doc.CreateReader();
            List<T> result = (List<T>)serializer.Deserialize(reader);
            reader.Close();
            return result;
        }
        catch (Exception e)
        {
            //perform logging / error handling
            return null;
        }

    }

    /// <summary>
    /// Converts a List<T> of entities into an XDoc.
    /// </summary>
    /// <typeparam name="T">Any serializable object</typeparam>
    /// <param name="paramList"></param>
    public static XDocument SerializeCollection<T>(List<T> paramList)
    {
        if (paramList == null)
            return null;

        XDocument doc = new XDocument();

        try
        {
            XmlSerializer serializer = new XmlSerializer(paramList.GetType());
            XmlWriter writer = doc.CreateWriter();
            serializer.Serialize(writer, paramList);
            writer.Close();
            return doc;
        }
        catch (Exception e)
        {
            //perform logging / error handling
            return null;
        }

    }
}

次の名前空間への参照を追加することを忘れないでください。

using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;

そうは言っても、DALは次のように呼ばれます。

//to retrieve the list of urls
List<Url> urls = UrlDAL.Retrieve();
//to save the new list of urls to an xml file
List<Url> urls = [BUILD URL ENTITIES FROM REPEATER];
UrlDAL.Create(urls)

編集: XMLを作成するためのヒント

XMLの逆シリアル化の問題を回避するために(XMLは解析対象について非常に扱いにくい場合があります)、コードで処理するクラスの一部(またはすべて)を作成し、Xml.Serializeメソッドを介してリストを実行する傾向があります。次に、そこで作成されたxmlを、XMLファイルを作成するための開始点として使用します。

編集リピーターからインスタンスを作成する

リピーターの各項目をループすると、次のように.NETのオブジェクト初期化子を使用できます。

List<Links> links = new List<Links>();
foreach (RepeaterItem item in rptLinks.Items)
{
   //find all your controls and their values
   string details = ((TextBox)e.Item.Findcontrol("txtDetails")).Text;
   //do this for each control

   //use object initialization here
   links.Add(new Link {Details = details, [PROPERTY NAME] = [REPEATER ITEM VALUE], etc});
}

この機能の適切な説明は、MSDNのここにあります:オブジェクトとコレクションの初期化子(C#プログラミングガイド)

HTH

于 2013-01-29T23:41:27.327 に答える
0

XmlDocument を使用して xml を読み込み、それをナビゲートして、変更する値を含む要素を見つけます。

System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
xmlDocument.Load(<filename or stream>);

Now, choose the most suitable method for you to find the elements or
attributes you want to change:

// For example:
XmlNodeList elemList = xmlDocument .GetElementsByTagName("Machine");
for (int i=0; i < elemList.Count; i++)
{
elemList[i].InnerXml = "Whateveryouwant";
}

次に、Save メソッドを呼び出して変更を保存します。

xmlDocument.Save(...);

于 2013-01-29T22:21:23.280 に答える