如何将字节数组转换为XML?

3

我有一个字节流,像这样:

byte[] response =
        {
            69, 90, 69, 45, 88, 77, 76, 45, 77, 115, 103, 48, 50, 60, 77, 101, 115, 115, 97, 103, 101, 62, 13, 10, 32,
            32, 60, 72, 101, 97, 100, 101, 114, 62, 13, 10, 32, 32, 32, 32, 60, 77, 101, 115, 115, 97, 103, 101, 68,
            97, 116, 101, 62, 50, 48, 49, 48, 48, 51, 50, 52, 60, 47, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116,
            101, 62, 13, 10, 32, 32, 32, 32, 60, 77, 101, 115, 115, 97, 103, 101, 84, 105, 109, 101, 62, 49, 57, 50,
            56, 48, 54, 60, 47, 77, 101, 115, 115, 97, 103, 101, 84, 105, 109, 101, 62, 13, 10, 32, 32, 60, 47, 72,
            101, 97, 100, 101, 114, 62, 13, 10, 32, 32, 60, 66, 111, 100, 121, 62, 13, 10, 32, 32, 32, 32, 60, 84,
            114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 73, 68, 62, 51, 51, 50, 53, 50, 55, 60, 47, 84, 114, 97,
            110, 115, 97, 99, 116, 105, 111, 110, 73, 68, 62, 13, 10, 32, 32, 32, 32, 60, 84, 114, 97, 110, 115, 97,
            99, 116, 105, 111, 110, 78, 117, 109, 98, 101, 114, 62, 49, 50, 49, 48, 52, 55, 48, 60, 47, 84, 114, 97,
            110, 115, 97, 99, 116, 105, 111, 110, 78, 117, 109, 98, 101, 114, 62, 13, 10, 32, 32, 32, 32, 60, 80,
            104, 111, 110, 101, 78, 117, 109, 98, 101, 114, 62, 54, 51, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 60,
            47, 80, 104, 111, 110, 101, 78, 117, 109, 98, 101, 114, 62, 13, 10, 32, 32, 32, 32, 60, 65, 109, 111,
            117, 110, 116, 62, 48, 48, 48, 48, 48, 48, 50, 53, 48, 48, 60, 47, 65, 109, 111, 117, 110, 116, 62, 13,
            10, 32, 32, 32, 32, 60, 82, 101, 115, 117, 108, 116, 62, 48, 51, 60, 47, 82, 101, 115, 117, 108, 116, 62,
            13, 10, 32, 32, 60, 47, 66, 111, 100, 121, 62, 13, 10, 60, 47, 77, 101, 115, 115, 97, 103, 101, 62
        };

我想从中提取xml。尝试了以下方法:

XmlDocument doc2 = new XmlDocument();
        MemoryStream ms = new MemoryStream(response);
        doc2.Load(ms);

但是遇到了一个异常:

在 System.Xml.dll 中发生了未处理的类型为“System.Xml.XmlException”的异常

额外的信息: 根级别上的数据无效。第1行,第1个位置。

我对xml一窍不通,doc2.load()方法应该做什么?它会创建任何我以后可以读取的xml文件吗?还是只是一个内存集合?

2个回答

4
问题在于您的byte []数组表示的字符串开头有一些非XML字符。如果我这样做:
string s;
using (var ms = new MemoryStream(response))
using (var reader = new StreamReader(ms))
{
    s = reader.ReadToEnd();

    Console.WriteLine(s);
}

我明白了。

EZE-XML-Msg02<Message>
  <Header>
    <MessageDate>20100324</MessageDate>
    <MessageTime>192806</MessageTime>
  </Header>
  <Body>
    <TransactionID>332527</TransactionID>
    <TransactionNumber>1210470</TransactionNumber>
    <PhoneNumber>639999999999</PhoneNumber>
    <Amount>0000002500</Amount>
    <Result>03</Result>
  </Body>
</Message>

首先需要删除EZE-XML-Msg02。最好的方法是在XML文件中一开始就不要存储它。但如果你无法阻止它被包含在XML文件中,可以采取以下步骤:

XmlDocument doc2 = new XmlDocument();
using (var ms = new MemoryStream(response))
using (var reader = new StreamReader(ms))
{
    while (!reader.EndOfStream && reader.Peek() > -1 && (char)reader.Peek() != '<')
        reader.Read();
    if (!reader.EndOfStream)
        doc2.Load(reader);
}

3

这是因为它是无效的XML。您完整的字符串如下:

EZE-XML-Msg02<Message>
  <Header>
    <MessageDate>20100324</MessageDate>
    <MessageTime>192806</MessageTime>
  </Header>
  <Body>
    <TransactionID>332527</TransactionID>
    <TransactionNumber>1210470</TransactionNumber>
    <PhoneNumber>639999999999</PhoneNumber>
    <Amount>0000002500</Amount>
    <Result>03</Result>
  </Body>
</Message>

多余的 "EZE-XML-Msg02" 导致了问题。您可以通过 string.Remove(如果您提前知道其长度)或 string.Split(',')并使用该长度来查找来删除它。更好的方法是,如果可能的话,首先阻止它进入 XML。

此时有几个注意事项。首先,您的解码方法肯定有效,但最好将 MemoryStream 放在 "using" 块内。另一种解码方法如下:

string str = ASCIIEncoding.ASCII.GetString(response);

它会为您解码字符串。您可以这样做:

doc2.LoadXml(str);

只需加载文档即可。这时,XmlDocument对象本身只是内存中的一个集合。您可以通过调用doc2.Save(filename)将其明确保存为文件。

另外请注意,有些人更喜欢使用LINQ版本(XDocument)而不是XML Document,以便可以对其运行LINQ查询。XmlDocument对象支持XPath查询,但效率有些低下,因为它无法静态编译查询,必须在运行时解析。然而,到底使用哪种方法取决于您具体的应用程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接