2

C#プロジェクト用にDTD(XSDおよびxsd.exe経由)からクラスを作成したので、コード内でそれらをモデルクラスに簡単に逆シリアル化できました。

これは大まかに私がそれを行う方法です:

XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.DtdProcessing = DtdProcessing.Parse;

XmlReader reader = XmlReader.Create(tipsfile.FullName, readerSettings);

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "Tips";
xRoot.IsNullable = true;

XmlSerializer serializer = new XmlSerializer(typeof(Tips), xRoot);
Tips tips = (Tips)serializer.Deserialize(reader);

reader.Close();

しかし、を調べてみるとtips、元のXMLファイルからの値がまったく保持されていないことがわかります。setまた、プロパティの-Bodyにブレークポイントを設定しようとしTipsましたが、元のXMLファイルに値があることは確かですが、到達することはありません。

ファイルがクラスに正しく逆シリアル化されないのはなぜですか?私のコードに何かが欠けていますか?

編集: XSDから自動生成されたTips.csファイルは次のとおりです

using System.Xml.Serialization;

namespace MyNs.Model
{
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/caravan_1")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/caravan_1", IsNullable = false)]
    public partial class Tips
    {
        private Chapter[] chapterField;

        [System.Xml.Serialization.XmlElementAttribute("Chapter")]
        public Chapter[] Chapter
        {
            get
            {
                return this.chapterField;
            }
            set
            {
                this.chapterField = value;
            }
        }
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/caravan_1")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/caravan_1", IsNullable = false)]
    public partial class Chapter
    {
        private string headingField;
        private CarType[] carTypesField;
        private Section[] sectionField;
        private string countryField;
        private string languageField;

        public string Heading
        {
            get
            {
                return this.headingField;
            }
            set
            {
                this.headingField = value;
            }
        }

        [System.Xml.Serialization.XmlArrayItemAttribute("CarType", IsNullable = false)]
        public CarType[] CarTypes
        {
            get
            {
                return this.carTypesField;
            }
            set
            {
                this.carTypesField = value;
            }
        }

        [System.Xml.Serialization.XmlElementAttribute("Section")]
        public Section[] Section
        {
            get
            {
                return this.sectionField;
            }
            set
            {
                this.sectionField = value;
            }
        }

        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string Country
        {
            get
            {
                return this.countryField;
            }
            set
            {
                this.countryField = value;
            }
        }

        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string Language
        {
            get
            {
                return this.languageField;
            }
            set
            {
                this.languageField = value;
            }
        }
    }
     [... and so on ...]

そしてサンプルXMLファイル:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Tips SYSTEM "caravan_1.dtd">
<Tips>
    <Chapter Country="dafghagt" Language="de">
        <Heading>fgagasgargaergarg</Heading>        
        <Section id="1">
            <Heading>afdhwr6u5taehtaqh5</Heading>
            <SubSection id="1">
                <Heading>46k46kw6jhadfgadfha</Heading>              
                <Table>
                    <Row id="1">
                        <Heading>sgjsfgjsgfh443q572q356</Heading>
                        <Items>
                            <Item car="motor1" id="1">
                                <BodyText color="red">130*</BodyText>
                                <Subscript>3</Subscript>
                            </Item>
                        </Items>
                    </Row>
                </Table>
            </SubSection>
        </Section>
    </Chapter>
</Tips>
4

3 に答える 3

2
        StreamReader sw = new StreamReader(fileName, false);
        XmlTextReader xmlw = new XmlTextReader(sw);
        XmlSerializer writer = new XmlSerializer(
            type,
            GetOverrides(),
            extraTypes,
            null,
            null);

        object o = writer.Deserialize(xmlw);

私のコメントによると、get overridesは、xml root属性に似たものを含むメソッドにすぎません。必要に応じて、これも表示できます。

編集:追加のタイプの例

    public Type[] GetTypes()
    {
        return new Type[] { typeof(Class1), typeof(Class2)};
    }

EDIT2:get overrides return(これはテストされていないことに注意してください)

XmlAttributes attribs = new XmlAttributes();
//attribs.XmlRoot - can edit root here (instead of xmlrootattribute)
attribs.XmlElements.Add(myAttribute);

XmlAttributeOverrides myOverride = new XmlAttributeOverrides();
myOverride.Add(typeof(Tips), "Tips", attribs);
return myOverride
于 2013-02-26T08:00:10.107 に答える
1

したがって、問題は名前空間であることがわかります。私のXMLにはルート名前空間がないため:

<Tips>

しかし、私のモデルの定義には次のものが含まれていました。

[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/caravan_1", IsNullable = false)]

シリアライザーはどの要素とも一致しませんでした。名前空間属性を削除すると、正常に機能しました。

だから今、私は完全なモデルを作り直し、絶対に必要ではない属性を除外しました(結局のところ、1つを除いてすべてが必要でした)ので、すべてのプロパティには1つの属性XmlElementとコンソートがあります。

using System.Xml.Serialization;

namespace MyNs.Model
{
    [XmlRoot("Tips")]
    public partial class Tips
    {
        [XmlElement("Chapter")]
        public Chapter[] Chapter { get; set; }
    }

    [XmlRoot("Chapter")]
    public partial class Chapter
    {
        [XmlElement("Heading")]
        public string Heading { get; set; }

        [XmlElement("CarType")]
        public CarType[] CarTypes { get; set; }

        [XmlElement("Section")]
        public Section[] Section { get; set; }

        [XmlAttribute("Country")]
        public string Country { get; set; }

        [XmlAttribute("Language")]
        public string Language { get; set; }
    }
    [... and so on ...]

単純な逆シリアル化で、今は問題なく動作します。

XmlReaderSettings readerSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse };
XmlSerializer serializer = new XmlSerializer(typeof(Tips));

using (XmlReader reader = XmlReader.Create(fromXmlFile.FullName, readerSettings))
{
    Tips tips = (Tips)serializer.Deserialize(reader);
    return tips;
}
于 2013-02-26T14:35:33.787 に答える
1

オブジェクトはxmlモデルと同一ではない可能性があります。その場合、クラスのプロパティをxmlフィールドにマップする必要があります。私のプロジェクトの1つで私が持っていた簡単な例を紹介します。これにより、もう少し情報が得られる可能性があります。

namespace DatabaseModel
{
    [Description("Represents the selected nodes in the Coverage pane")]
    [Serializable()]
    [XmlRootAttribute("XmlCoverage", Namespace = "GISManager", IsNullable = false)]
    public class TXmlCoverage : IXmlPolygon
    {
        [XmlArray(ElementName = "sbets"), XmlArrayItem(ElementName = "sbet")]
        public List SbetsSelected { get; set; }
        [XmlArray(ElementName = "sdcs"), XmlArrayItem(ElementName = "sdc")]
        public List SdcsSelected { get; set; }
        [XmlElementAttribute(ElementName = "area")]
        public Boolean IsAreaSelected { get; set; }
        [XmlElementAttribute(ElementName = "fpath")]
        public Boolean IsFlightPathSelected { get; set; }
        [XmlElementAttribute(ElementName = "fpoly")]
        public Boolean IsFlightPolySelected { get; set; }
        [XmlElementAttribute(ElementName = "mpoly")]
        public Boolean IsMinePolySelected { get; set; }
        [XmlElementAttribute(ElementName = "bldg")]
        public Boolean IsBuildingsSelected { get; set; }
        [XmlElementAttribute(ElementName = "hgt")]
        public Boolean IsHeightSelected { get; set; }
        [XmlIgnore()]
        public Boolean ArePolygonsSelected { get { return IsMinePolySelected && IsBuildingsSelected && IsHeightSelected; } }

    public TXmlCoverage()
    {
        SbetsSelected = new List<String>();
        SdcsSelected = new List<String>();
        IsAreaSelected = false;
        IsFlightPathSelected = false;
        IsFlightPolySelected = false;
    }
}

}

于 2013-02-25T16:03:03.563 に答える