根据RFC 3863的PIDF XML反序列化

时间:2017-11-03 07:30:05

标签: c# xml deserialization

我试图根据RFC(使用RFC中的XSD将XSD转换为C#类)将活动反序列化为对象类型活动,但似乎我遇到了活动xml元素的问题,因为它包含属性中的内部命名空间。

XML:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" entity="sip:anon@domain.invalid" xmlns:e="urn:ietf:params:xml:ns:pidf:status:rpid" xmlns:dm="urn:ietf:params:xml:ns:pidf:data-model" xmlns:ce="urn:cisco:params:xml:ns:pidf:rpid" xmlns:sc="urn:ietf:params:xml:ns:pidf:servcaps">
  <dm:person>
    <status>
    <basic>open</basic>
    </status>
    <e:activities>
    </e:activities>
  </dm:person>
</presence>

我将它反序列化为一个在线对象,取第一个(presence.Any [0]),并将其反序列化为一个人物对象,到目前为止一切都很好。但后来我想从person获取activity元素,并反序列化:

person.Any.SingleOrDefault(x => x.LocalName == "activities")

但是现在该对象的XML看起来像:

<e:activities xmlns:e="urn:ietf:params:xml:ns:pidf:status:rpid">
    </e:activities> 

如果我尝试将此反序列化为RFC3863中XSD的活动对象,我将以下面的错误消息结束:

Message "<activities xmlns='urn:ietf:params:xml:ns:pidf:status:rpid'> was not expected."

如何反序列化包含像这样的内部命名空间的XmlElements?

更新23-11-17(空元素):

XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:pp="urn:ietf:params:xml:ns:pidf:person" xmlns:es="urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status" xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person" entity="sip:Alice@10.24.18.124">
    <pp:person>
        <status>
            <ep:activities>
                <ep:away/>
            </ep:activities>
        </status>
    </pp:person>
    <note>Unavailable</note>
    <tuple id="6001">
        <contact priority="1">sip:6001@10.24.18.124</contact>
        <status>
            <basic>closed</basic>
        </status>
    </tuple>
</presence>

问题:

<ep:away xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person" />

数据实体:

[XmlType(TypeName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
public class Activities : activities
{
    [XmlElement(Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
    public ItemsChoiceType State { get; set; }
}


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:ietf:params:xml:ns:pidf:rpid", IncludeInSchema=false)]
public enum ItemsChoiceType {

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("##any:")]
    Item,

    /// <remarks/>
    appointment,

    /// <remarks/>
    away,

    /// <remarks/>
    breakfast,

    /// <remarks/>
    busy,

    /// <remarks/>
    dinner,

    /// <remarks/>
    holiday,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("in-transit")]
    intransit,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("looking-for-work")]
    lookingforwork,

    /// <remarks/>
    meal,

    /// <remarks/>
    meeting,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("on-the-phone")]
    onthephone,

    /// <remarks/>
    other,

    /// <remarks/>
    performance,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("permanent-absence")]
    permanentabsence,

    /// <remarks/>
    playing,

    /// <remarks/>
    presentation,

    /// <remarks/>
    shopping,

    /// <remarks/>
    sleeping,

    /// <remarks/>
    spectator,

    /// <remarks/>
    steering,

    /// <remarks/>
    travel,

    /// <remarks/>
    tv,

    /// <remarks/>
    unknown,

    /// <remarks/>
    vacation,

    /// <remarks/>
    working,

    /// <remarks/>
    worship,
}

1 个答案:

答案 0 :(得分:1)

您必须正确声明命名空间,尤其是默认命名空间。请参阅以下工作代码:

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

namespace ConsoleApplication1
{
    class Program
    {
        const string INPUT_FILENAME = @"c:\temp\test.xml";
        const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
        static void Main(string[] args)
        {

            Presence outPresence = new Presence()
            {
                person = new Person()
                {
                    status = new Status()
                    {
                        basic = "test"
                    },
                    activities = new Activities()
                    {
                    }
                }
            };
            XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
            xmlNameSpace.Add("dm", "urn:ietf:params:xml:ns:pidf:data-model");
            xmlNameSpace.Add("e", "urn:ietf:params:xml:ns:pidf:status:rpid");
            xmlNameSpace.Add("", "");

            XmlSerializer serializer = new XmlSerializer(typeof(Presence), "urn:ietf:params:xml:ns:pidf");

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;

            XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, settings);
            serializer.Serialize(writer, outPresence, xmlNameSpace);

            StreamReader reader = new StreamReader(INPUT_FILENAME);

            Presence presense = (Presence)serializer.Deserialize(reader);
        }

    }
    [XmlRoot(ElementName = "presence")]
    public class Presence
    {
        [XmlElement(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:data-model")]
        public Person person { get; set; }
    }
    [XmlRoot(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:data-model")]
    public class Person
    {
        [XmlElement(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
        public Status status { get; set; }

        [XmlElement(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:status:rpid")]
        public Activities activities { get; set; }
    }
    [XmlRoot(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
    public class Status
    {
        [XmlElement("basic")]
        public string basic { get; set; }
    }
    [XmlRoot(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:status:rpid")]
    public class Activities
    {
    }
}

更新代码11/23/17

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

namespace ConsoleApplication1
{
    class Program
    {
        const string INPUT_FILENAME = @"c:\temp\test.xml";
        const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
        static void Main(string[] args)
        {

            Presence outPresence = new Presence()
            {
                person = new Person()
                {
                    status = new Status()
                    {
                        basic = "test",
                        activities = new Activities()
                        {
                        }
                    },
                }
            };
            XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
            xmlNameSpace.Add("pp", "urn:ietf:params:xml:ns:pidf:person");
            xmlNameSpace.Add("ep", "urn:ietf:params:xml:ns:pidf:rpid:rpid-person");
            xmlNameSpace.Add("", "urn:ietf:params:xml:ns:pidf");

            XmlSerializer serializer = new XmlSerializer(typeof(Presence), "urn:ietf:params:xml:ns:pidf");

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;

            XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, settings);
            serializer.Serialize(writer, outPresence, xmlNameSpace);

            StreamReader reader = new StreamReader(INPUT_FILENAME);

            Presence presense = (Presence)serializer.Deserialize(reader);
        }

    }
    [XmlRoot(ElementName = "presence")]
    public class Presence
    {
        [XmlElement(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:person")]
        public Person person { get; set; }
    }
    [XmlRoot(ElementName = "person", Namespace = "urn:ietf:params:xml:ns:pidf:person")]
    public class Person
    {
        [XmlElement(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
        public Status status { get; set; }

    }
    [XmlRoot(ElementName = "status", Namespace = "urn:ietf:params:xml:ns:pidf")]
    public class Status
    {
        [XmlElement("basic")]
        public string basic { get; set; }

        [XmlElement(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
        public Activities activities { get; set; }

    }
    [XmlRoot(ElementName = "activities", Namespace = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person")]
    public class Activities
    {
        [XmlElement("away")]
        public string away { get; set; }
    }
}