2

我从 DTD(通过 XSD 和 xsd.exe)为我的 C# 项目创建了类,因此我可以轻松地将它们反序列化为我的代码中的模型类。

我大致是这样做的:

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 的属性的 -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 根属性的方法,如有必要,我也可以向您展示

编辑:额外类型的一个例子

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

EDIT2:获取覆盖返回(注意这是未经测试的)

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 模型不同。在这种情况下,您需要将类的属性映射到 xml 字段。我给你一个简单的例子,我在我的一个项目中可能会给你更多的信息。

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 回答
1

所以事实证明问题是命名空间。因为我的 XML 没有根命名空间:

<Tips>

但我的模型的定义包含一个:

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

序列化器没有将任何元素匹配在一起。删除命名空间属性时,它工作正常。

所以现在,我重新设计了完整的模型并排除了任何不是绝对必要的属性(事实证明,除了一个之外,所有属性都是),所以现在每个属性都只有一个属性: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 回答