【问题标题】:Deserialize XML to C# class error with unexpected type (2,2)使用意外类型将 XML 反序列化为 C# 类错误 (2,2)
【发布时间】:2020-10-15 09:17:36
【问题描述】:

目标是将 XML 文件反序列化为 c# 对象。 我使用this 站点来创建对象类。

当我尝试读取 XML 文件时,出现错误:

XML 文档 (2,2) 包含错误。 没想到

显然,部分课程缺少/错误,但我太新了,无法弄清楚。 有人可以帮帮我吗?

示例标头 XML

<?xml version="1.0" encoding="utf-8"?>       
<PXML_Document xmlns="http://progress-m.com/ProgressXML/Version1">
<DocInfo GlobalID="7C7E1FC5-0A46-48c5-A3B2-249D75B70BCF">
<MajorVersion>1</MajorVersion>
<MinorVersion>3</MinorVersion>
</DocInfo>
<Order>
<OrderNo>SF20-0178-BO</OrderNo>
<Storey>&lt;Storey /&gt;</Storey>
<DrawingDate>24/09/2020</DrawingDate>

C#类

using System;
using System.Collections.Generic;

using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Unitechnik_PXML_
{
public partial class Welcome2
{
    [JsonProperty("PXML_Document")]
    public PxmlDocument PxmlDocument { get; set; }
}

public partial class PxmlDocument
{
    [JsonProperty("DocInfo")]
    public DocInfo DocInfo { get; set; }

    [JsonProperty("Order")]
    public Order Order { get; set; }

    [JsonProperty("_xmlns")]
    public Uri Xmlns { get; set; }
}

public partial class DocInfo
{
    [JsonProperty("MajorVersion")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long MajorVersion { get; set; }

    [JsonProperty("MinorVersion")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long MinorVersion { get; set; }

    [JsonProperty("_GlobalID")]
    public string GlobalId { get; set; }
}

public partial class Order
{
    [JsonProperty("OrderNo")]
    public string OrderNo { get; set; }

    [JsonProperty("Storey")]
    public string Storey { get; set; }

    [JsonProperty("DrawingDate")]
    public string DrawingDate { get; set; }

    [JsonProperty("DrawingRevision")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long DrawingRevision { get; set; }

    [JsonProperty("ApplicationName")]
    public string ApplicationName { get; set; }

    [JsonProperty("ApplicationVersion")]
    public string ApplicationVersion { get; set; }

    [JsonProperty("OrderArea")]
    public string OrderArea { get; set; }

    [JsonProperty("Product")]
    public Product Product { get; set; }
}

public partial class Product
{
    [JsonProperty("ElementNo")]
    public string ElementNo { get; set; }

    [JsonProperty("ProductType")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long ProductType { get; set; }

    [JsonProperty("TotalThickness")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long TotalThickness { get; set; }

    [JsonProperty("DoubleWallsGap")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long DoubleWallsGap { get; set; }

    [JsonProperty("PieceCount")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long PieceCount { get; set; }

    [JsonProperty("TurnWidth")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long TurnWidth { get; set; }

    [JsonProperty("TurnMoveX")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long TurnMoveX { get; set; }

    [JsonProperty("RotationPosition")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long RotationPosition { get; set; }

    [JsonProperty("P1X")]
    public string P1X { get; set; }

    [JsonProperty("P1Y")]
    public string P1Y { get; set; }

    [JsonProperty("P1Z")]
    public string P1Z { get; set; }

    [JsonProperty("P2X")]
    public string P2X { get; set; }

    [JsonProperty("P2Y")]
    public string P2Y { get; set; }

    [JsonProperty("P2Z")]
    public string P2Z { get; set; }

    [JsonProperty("P3X")]
    public string P3X { get; set; }

    [JsonProperty("P3Y")]
    public string P3Y { get; set; }

    [JsonProperty("P3Z")]
    public string P3Z { get; set; }

    [JsonProperty("ItemPosition")]
    public string ItemPosition { get; set; }

    [JsonProperty("ElementInfo")]
    public string ElementInfo { get; set; }

    [JsonProperty("Slab")]
    public Slab Slab { get; set; }
}

public partial class Slab
{
    [JsonProperty("SlabNo")]
    public string SlabNo { get; set; }

    [JsonProperty("SlabArea")]
    public string SlabArea { get; set; }

    [JsonProperty("SlabWeight")]
    public string SlabWeight { get; set; }

    [JsonProperty("ProductionThickness")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long ProductionThickness { get; set; }

    [JsonProperty("MaxLength")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long MaxLength { get; set; }

    [JsonProperty("MaxWidth")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long MaxWidth { get; set; }

    [JsonProperty("ProjectCoordinates")]
    public string ProjectCoordinates { get; set; }

    [JsonProperty("GenericInfo01")]
    public string GenericInfo01 { get; set; }

    [JsonProperty("GenericInfo02")]
    public string GenericInfo02 { get; set; }

    [JsonProperty("GenericInfo03")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long GenericInfo03 { get; set; }

    [JsonProperty("Outline")]
    public Outline[] Outline { get; set; }
}

public partial class Outline
{
    [JsonProperty("Z")]
    public string Z { get; set; }

    [JsonProperty("Height")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long Height { get; set; }

    [JsonProperty("Name")]
    public string Name { get; set; }

    [JsonProperty("ConcreteQuality", NullValueHandling = NullValueHandling.Ignore)]
    public string ConcreteQuality { get; set; }

    [JsonProperty("UnitWeight")]
    public string UnitWeight { get; set; }

    [JsonProperty("Volume")]
    public string Volume { get; set; }

    [JsonProperty("Layer", NullValueHandling = NullValueHandling.Ignore)]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long? Layer { get; set; }

    [JsonProperty("Shape")]
    public ShapeUnion Shape { get; set; }

    [JsonProperty("_Type")]
    public TypeEnum Type { get; set; }

    [JsonProperty("X", NullValueHandling = NullValueHandling.Ignore)]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long? X { get; set; }

    [JsonProperty("Y", NullValueHandling = NullValueHandling.Ignore)]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long? Y { get; set; }

    [JsonProperty("GenericInfo02", NullValueHandling = NullValueHandling.Ignore)]
    public string GenericInfo02 { get; set; }

    [JsonProperty("MountPartDirection", NullValueHandling = NullValueHandling.Ignore)]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long? MountPartDirection { get; set; }

    [JsonProperty("MountPartType", NullValueHandling = NullValueHandling.Ignore)]
    public string MountPartType { get; set; }

    [JsonProperty("MountPartLength", NullValueHandling = NullValueHandling.Ignore)]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long? MountPartLength { get; set; }

    [JsonProperty("MountPartWidth", NullValueHandling = NullValueHandling.Ignore)]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long? MountPartWidth { get; set; }
}

public partial class ShapeElement
{
    [JsonProperty("SVertex")]
    public SVertex[] SVertex { get; set; }

    [JsonProperty("Cutout", NullValueHandling = NullValueHandling.Ignore)]
    [JsonConverter(typeof(FluffyParseStringConverter))]
    public bool? Cutout { get; set; }
}

public partial class SVertex
{
    [JsonProperty("X")]
    public string X { get; set; }

    [JsonProperty("Y")]
    public string Y { get; set; }

    [JsonProperty("Bulge")]
    [JsonConverter(typeof(PurpleParseStringConverter))]
    public long Bulge { get; set; }
}

public partial class PurpleShape
{
    [JsonProperty("SVertex")]
    public SVertex[] SVertex { get; set; }
}

public enum TypeEnum { Lot, Mountpart };

public partial struct ShapeUnion
{
    public PurpleShape PurpleShape;
    public ShapeElement[] ShapeElementArray;

    public static implicit operator ShapeUnion(PurpleShape PurpleShape) => new ShapeUnion { PurpleShape = PurpleShape };
    public static implicit operator ShapeUnion(ShapeElement[] ShapeElementArray) => new ShapeUnion { ShapeElementArray = ShapeElementArray };
}

public partial class Welcome2
{
    public static Welcome2 FromJson(string json) => JsonConvert.DeserializeObject<Welcome2>(json, Unitechnik_PXML_.Converter.Settings);
}

public static class Serialize
{
    public static string ToJson(this Welcome2 self) => JsonConvert.SerializeObject(self, Unitechnik_PXML_.Converter.Settings);
}

internal static class Converter
{
    public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
        DateParseHandling = DateParseHandling.None,
        Converters =
        {
            ShapeUnionConverter.Singleton,
            TypeEnumConverter.Singleton,
            new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
        },
    };
}

internal class PurpleParseStringConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null) return null;
        var value = serializer.Deserialize<string>(reader);
        long l;
        if (Int64.TryParse(value, out l))
        {
            return l;
        }
        throw new Exception("Cannot unmarshal type long");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        if (untypedValue == null)
        {
            serializer.Serialize(writer, null);
            return;
        }
        var value = (long)untypedValue;
        serializer.Serialize(writer, value.ToString());
        return;
    }

    public static readonly PurpleParseStringConverter Singleton = new PurpleParseStringConverter();
}

internal class ShapeUnionConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(ShapeUnion) || t == typeof(ShapeUnion?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        switch (reader.TokenType)
        {
            case JsonToken.StartObject:
                var objectValue = serializer.Deserialize<PurpleShape>(reader);
                return new ShapeUnion { PurpleShape = objectValue };
            case JsonToken.StartArray:
                var arrayValue = serializer.Deserialize<ShapeElement[]>(reader);
                return new ShapeUnion { ShapeElementArray = arrayValue };
        }
        throw new Exception("Cannot unmarshal type ShapeUnion");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        var value = (ShapeUnion)untypedValue;
        if (value.ShapeElementArray != null)
        {
            serializer.Serialize(writer, value.ShapeElementArray);
            return;
        }
        if (value.PurpleShape != null)
        {
            serializer.Serialize(writer, value.PurpleShape);
            return;
        }
        throw new Exception("Cannot marshal type ShapeUnion");
    }

    public static readonly ShapeUnionConverter Singleton = new ShapeUnionConverter();
}

internal class FluffyParseStringConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(bool) || t == typeof(bool?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null) return null;
        var value = serializer.Deserialize<string>(reader);
        bool b;
        if (Boolean.TryParse(value, out b))
        {
            return b;
        }
        throw new Exception("Cannot unmarshal type bool");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        if (untypedValue == null)
        {
            serializer.Serialize(writer, null);
            return;
        }
        var value = (bool)untypedValue;
        var boolString = value ? "true" : "false";
        serializer.Serialize(writer, boolString);
        return;
    }

    public static readonly FluffyParseStringConverter Singleton = new FluffyParseStringConverter();
}

internal class TypeEnumConverter : JsonConverter
{
    public override bool CanConvert(Type t) => t == typeof(TypeEnum) || t == typeof(TypeEnum?);

    public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null) return null;
        var value = serializer.Deserialize<string>(reader);
        switch (value)
        {
            case "lot":
                return TypeEnum.Lot;
            case "mountpart":
                return TypeEnum.Mountpart;
        }
        throw new Exception("Cannot unmarshal type TypeEnum");
    }

    public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
    {
        if (untypedValue == null)
        {
            serializer.Serialize(writer, null);
            return;
        }
        var value = (TypeEnum)untypedValue;
        switch (value)
        {
            case TypeEnum.Lot:
                serializer.Serialize(writer, "lot");
                return;
            case TypeEnum.Mountpart:
                serializer.Serialize(writer, "mountpart");
                return;
        }
        throw new Exception("Cannot marshal type TypeEnum");
    }

    public static readonly TypeEnumConverter Singleton = new TypeEnumConverter();
}

}

【问题讨论】:

  • 考虑不使用该网站。我不知道为什么它提出了如此复杂的 JSON.NET(注意 JSON.NET 中的 JSON 吗?)代码来解析 XML...
  • 我认为是XML文件的问题,检查格式是否正确,或者尝试使用在线XML解析器看是否可以成功解析,仔细查看哪些标签没有关闭(提示: 订单和 PXML_Document)
  • 首先:你的xml无效。第二:如果你有Visual Studio,你可以使用paste special命令并将xml粘贴为类。这样你应该有一个有效的可序列化类。

标签: c# xml serialization


【解决方案1】:

我不知道您是如何找到that site 的,以及为什么有人希望它能够工作。您粘贴 XML,然后返回 JSON 解析代码。这不会飞,JSON 不是 XML。修复 XML 时:

<?xml version="1.0" encoding="utf-8"?>
<PXML_Document xmlns="http://progress-m.com/ProgressXML/Version1">
  <DocInfo GlobalID="7C7E1FC5-0A46-48c5-A3B2-249D75B70BCF">
    <MajorVersion>1</MajorVersion>
    <MinorVersion>3</MinorVersion>
  </DocInfo>
  <Order>
    <OrderNo>SF20-0178-BO</OrderNo>
    <Storey>&lt;Storey /&gt;</Storey>
    <DrawingDate>24/09/2020</DrawingDate>
  </Order>
</PXML_Document>

并通过该站点生成代码,代码抛出:

Newtonsoft.Json.JsonReaderException: '解析值时遇到意外字符: <.>

就是这样。只需复制您的 XML,创建一个新文件,然后选择 Edit -&gt; Paste Special -&gt; Paste XML As Classes

然后你会得到几个可以与默认 XmlSerializer 一起使用的类:

var xmlDoc = new XmlSerializer(typeof(PXML_Document)).Deserialize(File.OpenRead("OrderData.xml"));

【讨论】:

  • 谢谢你!将特殊的 XML 粘贴为类就像一个魅力。
【解决方案2】:

文件中有 unicode 字符。如果您将代码放入记事本,然后执行另存为并将文件类型更改为 UTF-8,则 unicode 字符将被删除。我使用以下代码来测试您的 xml 和类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(PxmlDocument));
            PxmlDocument pxmlDocument = (PxmlDocument)serializer.Deserialize(reader);
 
        }

    }
    [XmlRoot(ElementName =  "PXML_Document", Namespace = "http://progress-m.com/ProgressXML/Version1")]
    public partial class PxmlDocument
    {
        public DocInfo DocInfo { get; set; }

        public Order Order { get; set; }

    }

    public partial class DocInfo
    {
        public long MajorVersion { get; set; }

        public long MinorVersion { get; set; }
    }
    public partial class Order
    {
        public string OrderNo { get; set; }

        public string Storey { get; set; }

        public string DrawingDate { get; set; }

        public long DrawingRevision { get; set; }

        public string ApplicationName { get; set; }

        public string ApplicationVersion { get; set; }

        public string OrderArea { get; set; }

        //public Product Product { get; set; }
    }



}

【讨论】:

  • “我完全改变了你的课程,它对我有用,所以问题一定是 Unicode”+1
猜你喜欢
  • 2011-08-09
  • 1970-01-01
  • 2020-12-09
  • 1970-01-01
  • 2017-08-22
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 2013-06-21
相关资源
最近更新 更多