如何从 Web API 收到的 xml 文件中提供数据 table?

How to feed data table from xml file received from Web API?

我的网站 API returns 一个看起来像下面 XML 文件的字符串。为了便于阅读,我将所有以 \r\n 结尾的行换行。

{"DataTable.RemotingVersion":{"major":2,"minor":0,"build":-1,"revision":-1,"majorRevision":-1,"minorRevision":-1},"XmlSchema":" <?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n
<xs:schema xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n  
<xs:element name=\"Test\">\r\n    
<xs:complexType>\r\n      
<xs:sequence>\r\n        
<xs:element name=\"Col1\" type=\"xs:string\" msdata:targetNamespace=\"\" minOccurs=\"0\" />\r\n        
<xs:element name=\"Col2\" type=\"xs:string\" msdata:targetNamespace=\"\" minOccurs=\"0\" />\r\n      
</xs:sequence>\r\n    
</xs:complexType>\r\n  
</xs:element>\r\n  
<xs:element name=\"tmpDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"Test\" msdata:UseCurrentLocale=\"true\">\r\n    
<xs:complexType>\r\n      
<xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\" />\r\n    
</xs:complexType>\r\n  
</xs:element>\r\n
</xs:schema>","XmlDiffGram":"<diffgr:diffgram xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" xmlns:diffgr=\"urn:schemas-microsoft-com:xml-diffgram-v1\">\r\n  
<tmpDataSet>\r\n    
<Test diffgr:id=\"Test1\" msdata:rowOrder=\"0\">\r\n      
<Col1>Column 1 value</Col1>\r\n      
<Col2>Column 2 value</Col2>\r\n    
</Test>\r\n  
</tmpDataSet>\r\n
</diffgr:diffgram>"}

我想知道如何将此字符串提供给数据table?我试着像这样 table

System.Data.DataTable dt =  new System.Data.DataTable();
byte[] byteArray  =Encoding.ASCII.GetBytes(<above string returned by Web API>);
MemoryStream stream = new MemoryStream( byteArray );
dt.ReadXml(stream);

然而,代码因异常而失败 System.Xml.XmlException: 'Data at the root level is invalid, position 1

  1. 实际上,您的 WebAPI 没有使用有效的 XML 负载进行响应,而是 return 一个 JSON
    {  
        "DataTable.RemotingVersion": {...},
        "XmlSchema":"... xml schema string ...",
        "XmlDiffGram": " ... xml data string ..."
    }
    
    所以你不能通过 dt.ReadXml(stream);
  2. 读取整个字符串
  3. 另请注意,xml 字符串以空字符串开头。最好在读取 XML 字符串之前调用 .Trim()

一个工作演示:

让我们创建两个辅助方法,将模式和数据部分读入 DataTable:

// read the schema into DataTable
public static void ReadSchema(DataTable dt,string schema)
{
    var stream = new MemoryStream();
    ReadXMLToMemoryStream(schema, stream);
    dt.ReadXmlSchema(stream);
}

// read the data into DataTable
public static void ReadData(DataTable dt,string xml)
{
    var stream = new MemoryStream();
    ReadXMLToMemoryStream(xml,stream);
    dt.ReadXml(stream);
}

// read xml string into MemoryStream
private static void ReadXMLToMemoryStream(string xml, MemoryStream stream)
{
    var doc = new XmlDocument();
    doc.LoadXml(xml.Trim());
    doc.Save(stream);
    stream.Position = 0;
}

要解决此问题,我们需要解析相关的 json 属性(我使用的是 Newtonsoft.Json):

byte[] bytes = Encoding.ASCII.GetBytes(strReturnedFromWebApi);
MemoryStream ms = new MemoryStream(bytes);
using(var reader = new JsonTextReader(new StreamReader(ms))){
    var json = JToken.Load(reader);
    var version= json.SelectToken("$.['DataTable.RemotingVersion']");
    var schema = (string)json.SelectToken("$.XmlSchema");    // the schema part
    var data = (string)json.SelectToken("$.XmlDiffGram");    // the data part

    System.Data.DataTable dt =  new System.Data.DataTable();
    ReadSchema(dt,schema);       // read schema
    ReadData(dt,data);           // read data
}