【问题标题】:Parsing XmlAttribute as complex type将 XmlAttribute 解析为复杂类型
【发布时间】: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 方法,但我得到的只是另一个例外。 有没有办法将此字符串反序列化到我的班级? 谢谢。

【问题讨论】:

    标签: c# xml svg


    【解决方案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:&lt;svg id="svg2"&gt; &lt;defs id="defs4" /&gt; &lt;metadata id="metadata7"&gt; &lt;rdf:RDF&gt; &lt;cc:Work rdf:about=""&gt; &lt;dc:format&gt;image/svg+xml&lt;/dc:format&gt; &lt;dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /&gt; &lt;dc:title&gt;&lt;/dc:title&gt; &lt;/cc:Work&gt; &lt;/rdf:RDF&gt; &lt;/metadata&gt; &lt;g id="layer1"&gt; &lt;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" /&gt; &lt;/g&gt; &lt;/svg&gt;
    猜你喜欢
    • 1970-01-01
    • 2013-07-09
    • 2020-04-10
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多