将 XmlAttribute 解析为复杂类型
Posted
技术标签:
【中文标题】将 XmlAttribute 解析为复杂类型【英文标题】:Parsing XmlAttribute as complex type 【发布时间】:2014-09-24 22:16:20 【问题描述】:我正在尝试创建 SVG 格式的对象模型。所以,由于它是 XML,我使用的是 XmlSerializer。但我有一个问题。有一些名为“样式”的 xml 属性。它看起来像复杂类型,但表示为字符串。有这个属性的例子:
style="fill:none;stroke:#00ff00;stroke-width:8.7489996;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:8.74900006"
如您所见,有“fill”、“stroke”、“stroke-width”等属性。 我写的课
public class SvgStyle
public string FillColor get; set;
public string StrokeColor get; set;
public float StrokeWidth get; set;
public int StrokeMiterlimit get; set;
public float StrokeOpacity get; set;
public float StrokeDashoffset get; set;
public string StrokeDasharray get; set;
和另一个班级
public abstract class SvgGraphicElement
[XmlAttribute("style")]
public SvgStyle Style get; set;
我得到的只是例外
无法序列化 Svg.SvgStyle 类型的成员“样式”。 XmlAttribute/XmlText 不能用于编码复杂类型。
我尝试使用 IXmlSerializable 接口实现和 OnSerializing/OnDeserializing 方法,但我得到的只是另一个例外。 有没有办法将此字符串反序列化到我的班级? 谢谢。
【问题讨论】:
【参考方案1】:我相信你需要在你的 SVGStyle 类上实现 IXmlSerializable 接口
http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx
刚刚读到您已经尝试过;对不起。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace XmlTypes
public class SvgStyle : IXmlSerializable
private const string fillColorKey = "fill";
private const string strokeColorKey ="stroke";
private const string strokeWidthKey = "stroke-width";
private const string strokeMiterLimitKey = "stroke-miterlimit";
private const string strokeOpacityKey ="stroke-opacity";
private const string strokeDashArrayKey="stroke-dasharray";
private const string strokeDashOffsetKey = "stroke-dashoffset";
[XmlAttribute]
public String Style get; set;
public string FillColor get; set;
public string StrokeColor get; set;
public float StrokeWidth get; set;
public int StrokeMiterlimit get; set;
public float StrokeOpacity get; set;
public float StrokeDashoffset get; set;
public string StrokeDasharray get; set;
public System.Xml.Schema.XmlSchema GetSchema()
return null;
public void ReadXml(System.Xml.XmlReader reader)
reader.MoveToContent();
Style = reader.GetAttribute("style");
Dictionary<string, string> lookupTable = ParseAttribute(Style);
FillColor = lookupTable[fillColorKey];
StrokeColor = lookupTable[strokeColorKey];
float strokeWidthFloatValue=0;
float.TryParse(lookupTable[strokeWidthKey] , out strokeWidthFloatValue) ;
StrokeWidth = strokeWidthFloatValue;
int strokeMiterLimitInt = 0;
Int32.TryParse(lookupTable[strokeMiterLimitKey] , out strokeMiterLimitInt);
StrokeMiterlimit = strokeMiterLimitInt;
int strokeOpacityInt = 0;
Int32.TryParse(lookupTable[strokeMiterLimitKey], out strokeOpacityInt);
StrokeOpacity = strokeOpacityInt;
int strokeDashOffsetInt = 0;
Int32.TryParse(lookupTable[strokeMiterLimitKey], out strokeDashOffsetInt);
StrokeDashoffset = strokeDashOffsetInt;
StrokeDasharray = lookupTable[strokeDashArrayKey];
Boolean isEmptyElement = reader.IsEmptyElement; // (1)
reader.ReadStartElement();
public void WriteXml(System.Xml.XmlWriter writer)
writer.WriteAttributeString("style", Style);
private Dictionary<string, string> ParseAttribute(string attribute)
string[] arr = attribute.Split(';');
Dictionary<string, string> dic = new Dictionary<string, string>();
for(int i = 0; i < arr.Length; i++)
string[] arrItem = arr[i].Split(':');
dic.Add(arrItem[0], arrItem[1]);
return dic;
[TestMethod]
public void TestMethod1()
string xml = @"<SvgStyle style='fill:none;stroke:#00ff00;stroke-width:8.7489996;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:8.74900006'></SvgStyle>";
XmlSerializer x = new XmlSerializer(typeof(SvgStyle));
SvgStyle myTest = (SvgStyle)x.Deserialize(new StringReader(xml));
【讨论】:
实现 IXmlSerializable 接口给了我另一个异常“无法序列化 Svg.SvgStyle 类型的成员 'Style'。XmlAttribute/XmlText 不能用于编码实现 IXmlSerializable 的类型”。那么,您能否详细说明我应该如何实现它?我在类上设置了所有属性,它的属性就像这个例子中的link。 在您的示例中,您合并了两个不同的实体,在我的例子中是 SvgGraphicElement 和 SvgStyle。也许这是我的错误,但是“样式”是 SvgGraphicElement 的属性,并且没有 SvgStyle 元素。目前看来我需要为 SvgGraphicElement 类实现 IXmlSerializable 接口,但不是 SvgStyle。 可以提供xml吗? 这是示例 xml:<svg id="svg2"> <defs id="defs4" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g id="layer1"> <rect width="497" height="177" id="rect2985" style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:54;stroke-miterlimit:51;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:50" /> </g> </svg>
以上是关于将 XmlAttribute 解析为复杂类型的主要内容,如果未能解决你的问题,请参考以下文章
XML 反序列化:在单个属性上使用 XmlAttribute 和 XmlText
使用 powershell 将嵌套的复杂 XML 解析为 CSV
在 C# visual2005 中使用 XmlAttribute() 检索