我试图根据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,
}
答案 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; }
}
}