Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm dealing with a number of large descriptive XML files that I only need to read the outer most elements, change the values and then save it out again.

As an example -

<Model Name="someModel">
    <Material Name="someMaterial" Effect="someEffect">
        <Texture Name="tex1" Path="somePath"/>
        <Colour Name="colour1" Value="FFF"/>
        <Layer Index="0"/>
        ... many more elements I don't are about
    </Material>
</Model>

I want to deserialize the above, change a Material attribute, and then save it back out again. But as I don't care about Materials elements (just its attributes), I'd rather not have to add them all to the class Im deserialzing too, .. however, I need them to still be written back out when I save.

At the moment, I'm doing this as follows, but I'm wondering if there's a better way.

namespace WpfApplication9
{
    public class Material
    {
        [XmlAttribute]
        public string Name
        {
            get;
            set;
        }

        [XmlAttribute]
        public string Effect
        {
            get;
            set;
        }
    }

    public class Item
    {
        [XmlAttribute]
        public string Name
        {
            get;
            set;
        }

        public Material Material
        {
            get;
            set;
        }

        public static Item Load(string _path)
        {
            Item item = new Item();
            item.m_doc = new XmlDocument();
            item.m_doc.Load(_path);

            XmlNode rootNode = item.m_doc.FirstChild;

            item.Name = rootNode.Attributes["Name"].InnerText;

            XmlNode materialNode = rootNode.FirstChild;

            item.Material = new Material();
            item.Material.Name = materialNode.Attributes["Name"].InnerText;
            item.Material.Effect = materialNode.Attributes["Effect"].InnerText;

            return item;
        }

        public void Save(string _path)
        {
            XmlNode rootNode = m_doc.FirstChild;

            rootNode.Attributes["Name"].InnerText = Name;

            XmlNode materialNode = rootNode.FirstChild;

            materialNode.Attributes["Name"].InnerText = Material.Name;
            materialNode.Attributes["Effect"].InnerText = Material.Effect;

            m_doc.Save(XmlWriter.Create(_path, new XmlWriterSettings()
            {
                IndentChars = "	",
                Indent = true
            }));
        }

        XmlDocument m_doc;
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Item item = Item.Load("Data.xml");
            item.Name = "Terry";
            item.Save("Data.xml");
        }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
330 views
Welcome To Ask or Share your Answers For Others

1 Answer

There is the XmlAnyElementAttribute. It instructs the deserializer to store unrecognized elements as is. However, depending on your case you might be better served using an XmlReader-XmlWriter filter, or an XmlDocument with XPath.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...