我有一个带索引条目的xml文件,如:
<xml>
<entry1>
...
</entry1>
<entry2>
...
</entry2>
</xml>
我使用xsd工具生成模式,然后使用c#类,显然它已创建:
public partial class entry1
...
public partial class entry2
如何更改类,以便在我运行序列化/反序列化时,它将识别并将它们命名为条目&#39; n&#39;在xml和我的对象中?
我需要使用相同类型的无限条目,并且无法更改xml。
答案 0 :(得分:1)
鉴于您无法更改XML,您将无法使用xsd.exe为此XML生成类。 XmlSerializer
对<entry1>
,<entry2>
,... <entryN>
等任意命名的元素没有内置支持。您可以在根类中实施IXmlSerializable
,从而启用XmlSerializer
来调用自定义(反)序列化代码,也可以使用XmlDocument
,XmlReader
或(我的推荐) )XDocument
直接读取XML,如果您认为有必要,构建一个对象模型。
ASIDE:如果可能,请反击此API。这违反了良好的XML设计。 XML是由它的自然顺序。 XML阅读<entry1/><entry2/>...<entryN/>
应该只是<entry/><entry/>...<entry/>
。 XML中的位置表示序列。
编辑:根据OP的评论,我将添加此内容。如果您的XML非常大,执行字符串替换可能不是最佳解决方案。您可以创建XmlReader
的子类,将<entryN>
元素替换为<entry>
个元素。您只需要覆盖LocalName
属性。请注意,我还没有安全&#34;这里 - 任何以&#34;条目&#34;开头的元素或属性将其名称更改为&#34; entry&#34;。我会留给你,以确定这是否足够你。如果没有,则在替换名称之前,当然可以执行其他状态检查(例如,确保您对某个元素进行了检查)。
// This class implements the LocalName override
private class CustomXmlReader : CustomXmlReaderBase
{
// constructor
public CustomXmlReader(XmlReader inner)
: base(inner)
{
}
// LocalName override
public override string LocalName
{
get { return base.LocalName.StartsWith("entry") ? "entry" : base.LocalName; }
}
}
// This class implements base behavior for an XML reader that wraps another XML reader.
private abstract class CustomXmlReaderBase : XmlReader
{
protected CustomXmlReaderBase(XmlReader inner)
{
_inner = inner;
}
private readonly XmlReader _inner;
public override string GetAttribute(string name)
{
return _inner.GetAttribute(name);
}
public override string GetAttribute(string name, string namespaceURI)
{
return _inner.GetAttribute(name, namespaceURI);
}
public override string GetAttribute(int i)
{
return _inner.GetAttribute(i);
}
public override bool MoveToAttribute(string name)
{
return _inner.MoveToAttribute(name);
}
public override bool MoveToAttribute(string name, string ns)
{
return _inner.MoveToAttribute(name, ns);
}
public override bool MoveToFirstAttribute()
{
return _inner.MoveToFirstAttribute();
}
public override bool MoveToNextAttribute()
{
return _inner.MoveToNextAttribute();
}
public override bool MoveToElement()
{
return _inner.MoveToElement();
}
public override bool ReadAttributeValue()
{
return _inner.ReadAttributeValue();
}
public override bool Read()
{
return _inner.Read();
}
public override string LookupNamespace(string prefix)
{
return _inner.LookupNamespace(prefix);
}
public override void ResolveEntity()
{
_inner.ResolveEntity();
}
public override XmlNodeType NodeType
{
get { return _inner.NodeType; }
}
public override string LocalName
{
get { return _inner.LocalName; }
}
public override string NamespaceURI
{
get { return _inner.NamespaceURI; }
}
public override string Prefix
{
get { return _inner.Prefix; }
}
public override string Value
{
get { return _inner.Value; }
}
public override int Depth
{
get { return _inner.Depth; }
}
public override string BaseURI
{
get { return _inner.BaseURI; }
}
public override bool IsEmptyElement
{
get { return _inner.IsEmptyElement; }
}
public override int AttributeCount
{
get { return _inner.AttributeCount; }
}
public override bool EOF
{
get { return _inner.EOF; }
}
public override ReadState ReadState
{
get { return _inner.ReadState; }
}
public override XmlNameTable NameTable
{
get { return _inner.NameTable; }
}
}