我有以下
`<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>1</name>
<value>
<struct>
<member>
<name>imageID</name>
<value>
<string>40087</string>
</value>
</member>
<member>
<name>imageURL</name>
<value> <string>http://local.server.gr/public_html/main/phpthumb/phpThumb.php?id=40087</string>
</value>
</member>
</struct>
</value>
</member>
<member>
<name>2</name>
<value>
<struct>
<member>
<name>imageID</name>
<value>
<string>40088</string>
</value>
</member>
<member>
<name>imageURL</name>
<value>
<string>http://local.server.gr/public_html/main/phpthumb/phpThumb.php?id=40088</string>
</value>
</member>
</struct>
</value>
</member>
<member>
<name>3</name>
<value>
<struct>
<member>
<name>imageID</name>
<value>
<string>40089</string>
</value>
</member>
<member>
<name>imageURL</name>
<value>
<string>http://local.server.gr/public_html/main/phpthumb/phpThumb.php?id=40089</string>
</value>
</member>
</struct>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>`
来自服务器的xmlrpc响应。
我尝试过接受并成功序列化这个xml的不同类型的对象,但没有成功。我无法理解&#34;名称&#34;更改整数值的元素。任何帮助表示赞赏。
答案 0 :(得分:1)
XML-RPC由Microsoft创建,并在2002年第一个.NET版本之前被SOAP取代。它的问题在于您不知道实际对象的架构是什么。 XML-RPC类似于Json,它将所有内容序列化为可用于重建对象属性的名称/值项。你不知道所有这些属性是什么。
> 幸运的是,Frontpage使用了XML-RPC,它的使用在SharePoint中幸存下来。这意味着您可以使用现成的架构here。
您可以使用旧的xsd.exe
程序从中生成C#类。将模式保存到文件(例如xmlrpc.xsd),确保标记之前没有空格,并使用以下行生成类:
xsd xmlrpc.xsd /c /nx:XlmRpcNS
其中XmlRpcNS
是您要用于生成的类的命名空间。将生成的文件添加到项目中(默认情况下为xmlrpc.cs
)并使用它们反序列化响应,例如:
using (var reader = new StringReader(response))
{
var sz = new XmlSerializer(typeof(methodResponse));
var methodResponse= (methodResponse)sz.Deserialize(reader);
var content = (methodResponseParams)methodResponse.Item;
var structContent = (StructType)content.param.value.Item;
//...
}
问题是xsd.exe
为每个选择元素生成object Item
属性,这就是你需要转换为正确类型的原因。
另一个选择是使用dynamic
来避免演员表。你这样失去了Intellisens:
dynamic methodResponse= (methodResponse)sz.Deserialize(reader);
var members = methodResponse.Item.param.value.Item;
答案 1 :(得分:0)
试试xml linq。在这种情况下工作真的很好
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication33
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("struct").FirstOrDefault().Elements("member").Select(x => new {
name = (int)x.Element("name"),
imageID = x.Descendants("member").Where(y => (string)y.Element("name") == "imageID").Select(z => (int)z.Descendants("string").FirstOrDefault()).FirstOrDefault(),
imageURL = x.Descendants("member").Where(y => (string)y.Element("name") == "imageURL").Select(z => (string)z.Descendants("string").FirstOrDefault()).FirstOrDefault(),
}).ToList();
}
}
}
进入班级
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication33
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Image.images = doc.Descendants("struct").FirstOrDefault().Elements("member").Select(x => new Image() {
name = (int)x.Element("name"),
imageID = x.Descendants("member").Where(y => (string)y.Element("name") == "imageID").Select(z => (int)z.Descendants("string").FirstOrDefault()).FirstOrDefault(),
url = x.Descendants("member").Where(y => (string)y.Element("name") == "imageURL").Select(z => (string)z.Descendants("string").FirstOrDefault()).FirstOrDefault(),
}).ToList();
}
}
public class Image
{
public static List<Image> images { get; set; }
public int name { get; set; }
public int imageID { get; set; }
public string url { get; set; }
}
}
答案 2 :(得分:0)
在考虑了你的答案之后,动态关键字让我想到这个解决方案并不完美,但是它的工作方式。 我将方法的返回类型设置为动态,然后在运行时使用visual studio调试器分析动态对象。然后我构建这个类:
public class ImageListResult
{
public List<ImageSlot> Slots { get; set; }
public ImageListResult(dynamic res)
{
this.Slots = new List<ImageSlot>();
try {
int keys = res.Keys.Count;
int values = res.Values.Count;
if (keys == values)
{
for (int i = 0; i < keys; i++)
{
ImageSlot slot = new ImageSlot()
{
Index = int.Parse(res.Keys[i])
};
int subCount = res.Values[i].Keys.Count;
for (int j = 0; j < subCount; j++)
{
string k = res.Values[i].Keys[j];
string v = res.Values[i].Values[j];
if (k.ToLower().Trim() == "imageid")
{
slot.ImageId = v;
}
else if(k.ToLower().Trim() == "imageurl")
{
slot.ImageUrl = v;
}
}
this.Slots.Add(slot);
}
}
}catch(Exception ex)
{
}
}
public class ImageSlot
{
/// <summary>
/// το index του image slot, απο το 1 εως το 25
/// </summary>
public int Index { get; set; }
public string ImageId { get; set; }
public string ImageUrl { get; set; }
}
}
所以我成功地设法反序列化了响应。它不理想,但还行。如果有人想到一个更好的解决方案随时发布它,谢谢你的答案