如何将.xml文件与xmlns属性一起反序列化?

| 我正在尝试学习反序列化。我已经编写了这段代码以反序列化* .hbm.xml文件。 每个元素都正确加载,但\“ xmlns \”。异常中的消息是:
<hibernate-mapping xmlns=\'urn:nhibernate-mapping-2.2\'> was not expected.
应该怎么做才能解决这个问题? 您想查看我的完整代码吗? 干得好:
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<hibernate-mapping
assembly=\"Sample.CustomerService.Domain\" namespace=\"Sample.CustomerService.Domain\"
>
  <class name=\"MyTable\" table=\"MyTable\" lazy=\"true\" >
    <id name=\"ID\">
      <generator class=\"identity\" />
      <column name=\"ID\" sql-type=\"int\" not-null=\"true\" />
    </id>
    <property name=\"Name\">
      <column name=\"Name\" sql-type=\"varchar\" not-null=\"false\" />
    </property>
    <property name=\"MfgDate\">
      <column name=\"MfgDate\" sql-type=\"datetime\" not-null=\"true\" />
    </property>
  </class>
</hibernate-mapping>
public class Class
    {
        [XmlAttribute(\"name\")]
        public string Name { get; set; }

        [XmlAttribute(\"table\")]
        public string Table { get; set; }

        [XmlAttribute(\"lazy\")]
        public bool Lazy { get; set; }

        [XmlElement(\"id\")]
        public Id Id { get; set; }

        [XmlElement(\"property\")]
        public Property [] Properties { get; set; }
    }

 public class Column
    {
        [XmlAttribute(\"name\")]
        public string ColumnName { get; set; }

        [XmlAttribute(\"sql-type\")]
        public string SqlTypeName { get; set; }

        [XmlAttribute(\"not-null\")]
        public bool NotNull { get; set; }
    }

public class Generator
    {
        [XmlAttribute(\"class\")]
        public string Class { get; set; }
    }

[XmlRoot(\"hibernate-mapping\", Namespace = \"urn:nhibernate-mapping-2.2\")]
    public class HibernateMapping
    {
        [XmlAttribute(\"assembly\")]
        public string AssemblyName { get; set; }

        [XmlAttribute(\"namespace\")]
        public string NamespaceName { get; set; }

        [XmlElement(\"class\")]
        public Class Class { get; set; }

        public override string  ToString()
        {
            StringBuilder sb = new StringBuilder(NamespaceName);
            sb.Append(\".\");
            sb.Append(Class.Name);

            return sb.ToString();
        }
    }

public class Id
    {
        [XmlElement(\"generator\")]
        public Generator Generator { get; set; }

        [XmlElement(\"column\")]
        public Column Column { get; set; }
    }

public class Property
    {
        [XmlAttribute(\"name\")]
        public string Name { get; set; }

        [XmlAttribute(\"column\")]
        public string Column { get; set; }

        [XmlAttribute(\"type\")]
        public string SqlTypeName { get; set; }

        [XmlAttribute(\"not-null\")]
        public bool NotNull { get; set; }

        [XmlElement(\"column\")]
        public Column PropColumn { get; set; }

        public string GetColumnName()
        {
            if (PropColumn != null)
            {
                return PropColumn.ColumnName;
            }
            else
            {
                return Name;
            }
        }

        public string GetSqlTypeName()
        {
            if (PropColumn != null)
            {
                return PropColumn.SqlTypeName;
            }
            else
            {
                return SqlTypeName;
            }
        }

        public bool GetNotNull()
        {
            if (PropColumn != null)
            {
                return PropColumn.NotNull;
            }
            else
            {
                return NotNull;
            }
        }
    }

class Program
    {
        static void Main(string[] args)
        {
            //IList<HibernateMapping> list = HbmReader.Get(\"How_To_Deserialize_a_Hbm_File\");
//            string xml = @\"<?xml version=\"\"1.0\"\" encoding=\"\"utf-8\"\" ?>
//<hibernate-mapping xmlns=\"\"urn:nhibernate-mapping-2.2\"\">
//    <class name=\"\"Example.Library.Resources.TestObject, Example.Library\"\" table=\"\"test_object\"\" lazy=\"\"false\"\">
//        <id name=\"\"TestId\"\" column=\"\"TestId\"\" type=\"\"Guid\"\"> 
//            <generator class=\"\"assigned\"\" /> 
//        </id> 
//        <property name=\"\"Name\"\" type=\"\"String\"\" length=\"\"45\"\" />
//    </class>
//</hibernate-mapping>\";

            Assembly assembly = Assembly.Load(\"Sample.CustomerService.Domain\");
            string[] manifestResourceNames = assembly.GetManifestResourceNames();

            XmlSerializer ser = new XmlSerializer(typeof(HibernateMapping));

            Stream stream = assembly.GetManifestResourceStream(manifestResourceNames[0]);

            HibernateMapping obj = (HibernateMapping)ser.Deserialize(new StreamReader(stream));

            Console.WriteLine(obj.Class.Name);
            Console.WriteLine(obj.Class.Table);
            foreach (var prop in obj.Class.Properties)
            {
                Console.WriteLine(\"prop: \" + prop.Name);
            }

            string str = string.Empty;
        }
    }
    
已邀请:
只需使用
XmlRoot
XmlType
XmlAttribute
XmlElement
(等)上的
Namespace
属性即可解决;示例如下所示: 输出:
Example.Library.Resources.TestObject, Example.Library
test_object
prop: Name
Xml(从此处开始):
<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<hibernate-mapping xmlns=\"urn:nhibernate-mapping-2.2\">
    <class name=\"Example.Library.Resources.TestObject, Example.Library\" table=\"test_object\" lazy=\"false\">
        <id name=\"TestId\" column=\"TestId\" type=\"Guid\"> 
            <generator class=\"assigned\" /> 
        </id> 
        <property name=\"Name\" type=\"String\" length=\"45\" />
    </class>
</hibernate-mapping>
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

[XmlRoot(\"hibernate-mapping\", Namespace = \"urn:nhibernate-mapping-2.2\")]
public class HibernateMapping
{
    [XmlAttribute(\"assembly\")]
    public string AssemblyName { get; set; }

    [XmlElement(\"class\")] // should this be a list?
    public Class Class { get; set; }
}

public class Class
{
    [XmlAttribute(\"name\")]
    public string Name { get; set; }

    [XmlAttribute(\"table\")]
    public string Table { get; set; }

    private readonly List<Property> properties = new List<Property>();
    [XmlElement(\"property\")]
    public List<Property> Properties { get { return properties; } }
}
public class Property
{
    [XmlAttribute(\"name\")]
    public string Name { get; set; }
}
static class Program
{
    static void Main()
    {
        File.WriteAllText(\"my.xml\",
                          @\"<?xml version=\"\"1.0\"\" encoding=\"\"utf-8\"\" ?>
<hibernate-mapping xmlns=\"\"urn:nhibernate-mapping-2.2\"\">
    <class name=\"\"Example.Library.Resources.TestObject, Example.Library\"\" table=\"\"test_object\"\" lazy=\"\"false\"\">
        <id name=\"\"TestId\"\" column=\"\"TestId\"\" type=\"\"Guid\"\"> 
            <generator class=\"\"assigned\"\" /> 
        </id> 
        <property name=\"\"Name\"\" type=\"\"String\"\" length=\"\"45\"\" />
    </class>
</hibernate-mapping>\");


        var ser = new XmlSerializer(typeof(HibernateMapping));
        var obj = (HibernateMapping)ser.Deserialize(new StreamReader(\"my.xml\"));
        Console.WriteLine(obj.Class.Name);
        Console.WriteLine(obj.Class.Table);
        foreach (var prop in obj.Class.Properties)
        {
            Console.WriteLine(\"prop: \" + prop.Name);
        }
        Console.ReadKey();
    }
}
请注意,我只映射了一些xml值-但它应该表明它实际上是有效的。     
xmlns
(XML名称空间)属性保留给XML。 XmlSerializer永远不会将其返回给您的类。     
自.NET类型以来,序列化程序不了解XML名称空间 没有声明。 您需要添加以下属性,以确保序列化程序将 考虑名称空间:
[System.Xml.Serialization.XmlTypeAttribute(Namespace=\"urn:nhibernate-mapping-2.2\")]
[System.Xml.Serialization.XmlRootAttribute(\"SupportedAgreementType\", Namespace=\"urn:nhibernate-mapping-2.2\", Nullable=false)]
    
可以尝试使用IXmlSerializable,而不是尝试自动实现反序列化。习惯后,它真的很容易,而且非常灵活。您可以使用私有支持而不是公共访问器实例化只读属性。它比属性映射更为冗长,但是这里有一些您可以使用的代码(我在这里和那里做的事情有所不同,以使您了解事物的工作方式):
[Serializable(), XmlRoot(\"hibernate-mapping\", Namespace = \"urn:nhibernate-mapping-2.2\")]
public class HibernateMapping : IXmlSerializable
{
    public string AssemblyName { get; set; }
    public string NamespaceName { get; set; }
    public Class Class { get; set; }
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder(NamespaceName);
        sb.Append(\".\");
        sb.Append(Class.Name);
        return sb.ToString();
    }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        AssemblyName = reader[\"assembly\"];
        NamespaceName = reader[\"namespace\"];

        XmlSerializer classSerializer = new XmlSerializer(typeof(Class));

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.LocalName)
                {
                    case \"class\":
                        Class = (Class)classSerializer.Deserialize(reader.ReadSubtree());
                        break;
                }
            }
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        throw new NotImplementedException();
    }
}

public class Column
{
    public string ColumnName { get; set; }
    public string SqlTypeName { get; set; }
    public bool NotNull { get; set; }
}

public class Generator
{
    public string Class { get; set; }
}

public class Id
{
    public Generator Generator { get; set; }
    public Column Column { get; set; }
}

public class Property
{
    public string Name { get; set; }
    public string Column { get; set; }
    public string SqlTypeName { get; set; }
    public bool NotNull { get; set; }
    public Column PropColumn { get; set; }
    public string GetColumnName()
    {
        if (PropColumn != null) { return PropColumn.ColumnName; }
        else { return Name; }
    }
    public string GetSqlTypeName()
    {
        if (PropColumn != null) { return PropColumn.SqlTypeName; }
        else { return SqlTypeName; }
    }
    public bool GetNotNull()
    {
        if (PropColumn != null) { return PropColumn.NotNull; }
        else { return NotNull; }
    }
}

[Serializable(), XmlRoot(\"class\")]
public class Class : IXmlSerializable
{
    public string Name { get; set; }
    public string Table { get; set; }
    public bool Lazy { get; set; }
    public Id Id { get; set; }
    public Property[] Properties { get; set; }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        Name = reader[\"name\"];
        Table = reader[\"table\"];
        Lazy = Convert.ToBoolean(reader[\"lazy\"]);

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.LocalName)
                {
                    case \"id\":
                        ReadIdXml(reader.ReadSubtree());
                        break;
                    case \"property\":
                        ReadPropertyXml(reader.ReadSubtree());
                        break;
                }
            }
        }
    }

    private void ReadIdXml(XmlReader reader)
    {
        //you can read the attributes and subnodes of the id node as above...
        Id = new Id();

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.LocalName)
                {
                    case \"generator\":
                        Id.Generator = new Generator();
                        Id.Generator.Class = reader[\"class\"];
                        break;
                    case \"column\":
                        Id.Column = ReadColumnXml(reader.ReadSubtree());
                        break;
                }
            }
        }
    }

    private void ReadPropertyXml(XmlReader reader)
    {
        Property property = new Property();
        property.Name = reader[\"name\"];

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.LocalName)
                {
                    case \"generator\":
                        property.PropColumn = ReadColumnXml(reader.ReadSubtree());
                        break;
                }
            }
        }

    }

    private Column ReadColumnXml(XmlReader reader)
    {
        Column column = new Column();
        column.ColumnName = reader[\"name\"];
        column.SqlTypeName = reader[\"sql-type\"];
        column.NotNull = Convert.ToBoolean(reader[\"non-null\"]);
        return column;
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        throw new NotImplementedException();
    }
}
    

要回复问题请先登录注册