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

时间:2019-09-09 23:29:08

标签: ado.net asp.net-core-webapi

我的Web API返回一个类似于下面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>"}

我想知道如何将这个字符串提供给数据表吗?我试图像这样喂桌子

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 个答案:

答案 0 :(得分:0)

  1. 实际上,您的WebAPI并未以有效的XML有效负载进行响应,而是返回了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
}