读取XML文件的内容而不必删除XML声明

时间:2011-12-16 19:01:03

标签: c# xml xml-declaration

我想从文件中读取所有XML内容。以下代码仅在删除XML声明( <?xml version="1.0" encoding="UTF-8"?> )时有效。在不删除XML声明的情况下读取文件的最佳方法是什么?

XmlTextReader reader = new XmlTextReader(@"c:\my path\a.xml");
            reader.Read();
            string rs = reader.ReadOuterXml();

如果不删除XML声明,reader.ReadOuterXml()将返回一个空字符串。

<?xml version="1.0" encoding="UTF-8"?>  
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.as.com/ver/ver.IClaimver/Car</a:Action>
    <a:MessageID>urn:uuid:b22149b6-2e70-46aa-8b01-c2841c70c1c7</a:MessageID>
    <ActivityId CorrelationId="16b385f3-34bd-45ff-ad13-8652baeaeb8a" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">04eb5b59-cd42-47c6-a946-d840a6cde42b</ActivityId>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <a:To s:mustUnderstand="1">http://localhost/ver.Web/ver2011.svc</a:To>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Car xmlns="http://www.as.com/ver">
      <carApplication>
        <HB_Base xsi:type="HB" xmlns="urn:core">
          <Header>
            <Advisor>
              <AdvisorLocalAuthorityCode>11</AdvisorLocalAuthorityCode>
              <AdvisorType>1</AdvisorType>
            </Advisor>
          </Header>
          <General>
            <ApplyForHB>yes</ApplyForHB>
            <ApplyForCTB>yes</ApplyForCTB>
            <ApplyForFSL>yes</ApplyForFSL>
            <ConsentSupplied>no</ConsentSupplied>
            <SupportingDocumentsSupplied>no</SupportingDocumentsSupplied>
          </General>
        </HB_Base>
      </carApplication>
    </Car>
  </s:Body>
</s:Envelope>

更新

我知道其他使用NON-xml阅读器的方法(例如使用File.ReadAllText())。但我需要知道一种使用xml方法的方法。

5 个答案:

答案 0 :(得分:6)

除了BOM之外,<?xml ?>编码声明之前不能有文本或空格,声明和除断行之外的根元素之间不能有文本。

其他任何内容都是无效的文件。

更新:

我认为您对XmlTextReader.read()的期望是错误的。

每次调用XmlTextReader.Read()都会逐步执行XML文档中的下一个“标记”,一次一个标记。“标记”表示XML元素,空格,文本和XML编码声明。

您对reader.ReadOuterXML()的调用返回一个空字符串,因为XML文件中的第一个标记是XML声明,而XML声明没有OuterXML。

考虑以下代码:

    XmlTextReader reader = new XmlTextReader("test.xml");
    reader.Read();
    Console.WriteLine(reader.NodeType);  // XMLDeclaration
    reader.Read();
    Console.WriteLine(reader.NodeType);  // Whitespace
    reader.Read();
    Console.WriteLine(reader.NodeType);  // Element
    string rs = reader.ReadOuterXml();

上面的代码产生了这个输出:

XmlDeclaration
Whitespace
Element

第一个“标记”是XML声明。

遇到的第二个“标记”是XML声明后的换行符。

遇到的第三个“标记”是<s:Envelope>元素。从这里调用reader.ReadOuterXML()将返回我认为你期望看到的内容 - <s:Envelope>元素的文本,这是整个soap包。

如果你真正想要的是将XML文件作为对象加载到内存中,只需调用即可  var doc = XDocument.Load("test.xml") 并一举完成解析。

除非你正在处理一个巨大的XML文档,以至于它不适合系统内存,否则实际上没有太多理由一次只能在XML文档中查找一个令牌。

答案 1 :(得分:2)

怎么样?
XmlDocument doc=new XmlDocument;
doc.Load(@"c:\my path\a.xml");
//Now we have the XML document - convert it to a String
//There are many ways to do this, one should be:
StringWriter sw=new StringWriter();
doc.Save(sw);
String finalresult=sw.ToString();

答案 2 :(得分:1)

编辑:我假设你的意思是实际上在文档声明和根元素之间有文本。如果情况并非如此,请澄清。

在不删除额外文本的情况下,它只是一个无效的XML文件。我不会期望它起作用。你没有XML文件 - 你有点像XML文件,但在根元素之前有无关紧要的东西。

答案 3 :(得分:1)

恕我直言,你无法阅读这个文件。这是因为在根元素<s:Envelope>之前有一个纯文本,这使得整个文档无效。

答案 4 :(得分:0)

您是将XML文档解析为XML只是为了获取源文本?为什么呢?

如果你真的想那么做:

string rs;
using(var rdr = new StreamReader(@"c:\my path\a.xml"))
  rs = rdr.ReadToEnd();

会工作,但我真的不确定这是你真正想要的。这几乎忽略了它是XML而只是读取文本。对某些事情很有用,但不是很多。