我正在编写一个加载XML文件的程序,并使用这些数据在Unity中创建对象。创建XmlSerializer对象会导致以下错误:
InvalidOperationException: The XML element named 'compatibility' from namespace ''
is already present in the current scope. Use XML attributes to specify another
XML name or namespace for the element.
这表明Unity在某些看不见的/内部项目代码上有[XmlElement(ElementName = "compatibility")]
或类似的属性。作为旁注,我编写了一个没有这个问题的简单控制台应用程序,使用完全相同的代码(少了一两个Unity特定函数)。
我无法编辑我正在读取的XML(因为它是由另一个程序生成的),它没有指定命名空间。
我已尝试在序列化类中设置部分或全部元素的Namespace属性,但我总是以“意外的< eagle xmlns ='1,4,4”或类似错误结束。我也试过通过XSD工具生成文件,与上面的“意外”错误相同。最后,我尝试创建一个XmlNamespaceManager对象,创建并推送一个新的命名空间,但它似乎没有效果。
我该怎么做才能解决这个问题?
XML片段(注意,不包括整个文件,因为它大约有500行.XML格式正确)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE eagle SYSTEM "eagle.dtd">
<eagle version="8.4.3">
<drawing>
<settings>
<setting alwaysvectorfont="no"/>
<setting verticaltext="up"/>
</settings>
<grid distance="50" unitdist="mil" unit="mil" style="lines" multiple="1" display="no" altdistance="5" altunitdist="mil" altunit="mil"/>
<layers>
<layer number="1" name="Top" color="4" fill="1" visible="yes" active="yes"/>
<layer number="2" name="Route2" color="1" fill="3" visible="no" active="no"/>
<layer number="3" name="Route3" color="4" fill="3" visible="no" active="no"/>
类XML被序列化为:
using System;
using System.Xml.Serialization;
namespace Assets.Scripts
{
[Serializable()]
[XmlRoot(ElementName = "eagle")]
public partial class EagleXML
{
[XmlElement(ElementName = "compatibility", Order = 0)]
public CompatibilityNote CompatibilityNote1 { get; set; }
[XmlElement(ElementName = "drawing", Order = 1)]
public Drawing Drawing { get; set; }
[XmlElement(ElementName = "compatibility", Order = 2)]
public CompatibilityNote CompatibilityNote2 { get; set; }
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
}
[Serializable()]
public partial class CompatibilityNote
{
}
[Serializable()]
public partial class Drawing
{
}
}
进行反序列化的类:
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using UnityEngine;
namespace Assets.Scripts
{
public class PCBScript : MonoBehaviour
{
public const string brdPath = @"ProperPathToXmlFile";
void Start()
{
XmlReaderSettings settings = new XmlReaderSettings();
XmlUrlResolver resolver = new XmlEagleUrlResolver();
settings.ProhibitDtd = false;
settings.ValidationType = ValidationType.None;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationFailed);
settings.XmlResolver = resolver;
XmlSerializer serializer = new XmlSerializer(typeof(EagleXML));
EagleXML loadedFile = (EagleXML)serializer.Deserialize(XmlReader.Create(brdPath, settings));
Console.WriteLine("Loaded xml");
}
private void ValidationFailed(object sender, ValidationEventArgs e)
{
Console.WriteLine("Failed to validate");
Console.WriteLine(e.Message);
Console.WriteLine("\r\n");
}
}
}