2016-12-16 53 views
1

我有以下从服务器XML RPC响应地图到对象C#

`<?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对象而不是成功。我无法理解更改整数值的“name”元素。任何帮助表示赞赏。

+0

广东话从乌尔描述得到 - 你需要序列化或反序列化到C#对象? – Mitklantekutli

+0

即使在2002年推出.NET的第一个版本之前,XML-RPC也被SOAP取代。本质上,它是一组类似于Json的键/值对(实际名称/值对)。如果你无法说服那些创建服务器的人使用更多...新鲜的,你应该找一个像库[XML-RPC.Net(http://xml-rpc.net/),也可作为NuGet包 –

+0

@Mitklantekutli问题是明确的 - OP要deserialze服务器响应。这不是直接的,因为*元素*具有不同的内容和结构,就像Json一样。 –

回答

1

XML-RPC是由微软创建,并在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; 
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; } 
    } 


} 
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; } 
    } 

} 

所以我成功设法反序列化的响应。它不理想,但它确定。如果有人认为更好的解决方案的随意张贴,感谢您的回答

+0

您是否尝试XML-RPC.NET?或者检查一个*替代* API?例如,SharePoint具有SOAP和REST API,它们提供与XML-RPC相同的功能。 –

+0

我用CookComputing.XmlRpcV2库。在这种情况下,我只能使用XML-RPC。感谢 –

+0

你试试我的解决办法是少了很多代码,不使用第二方的dll,并给出了相同的结果? – jdweng