要使用任意编码加载XML文件,我有以下代码:
Encoding encoding;
using (var reader = new XmlTextReader(filepath))
{
reader.MoveToContent();
encoding = reader.Encoding;
}
var settings = new XmlReaderSettings { NameTable = new NameTable() };
var xmlns = new XmlNamespaceManager(settings.NameTable);
var context = new XmlParserContext(null, xmlns, "", XmlSpace.Default,
encoding);
using (var reader = XmlReader.Create(filepath, settings, context))
{
return XElement.Load(reader);
}
Run Code Online (Sandbox Code Playgroud)
这有效,但打开文件两次似乎有点低效.是否有更好的方法来检测编码,以便我可以这样做:
1. Open file
2. Detect encoding
3. Read XML into an XElement
4. Close file
Run Code Online (Sandbox Code Playgroud) 我的应用程序中有以下XML解析代码:
public static XElement Parse(string xml, string xsdFilename)
{
var readerSettings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
Schemas = new XmlSchemaSet()
};
readerSettings.Schemas.Add(null, xsdFilename);
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
readerSettings.ValidationEventHandler +=
(o, e) => { throw new Exception("The provided XML does not validate against the request's schema."); };
var readerContext = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.UTF8);
return XElement.Load(XmlReader.Create(new StringReader(xml), readerSettings, readerContext));
}
Run Code Online (Sandbox Code Playgroud)
我用它来解析发送到我的WCF服务的字符串到XML文档,用于自定义反序列化.
当我读入文件并通过网络发送它们时(请求),它工作正常; 我已经确认没有发送BOM.在我的请求处理程序中,我正在序列化响应对象并将其作为字符串发送回来.序列化过程将UTF-8 BOM添加到字符串的前面,这会导致在解析响应时中断相同的代码.
System.Xml.XmlException : Data at the root level is …Run Code Online (Sandbox Code Playgroud) 所以我在里面使用文件流 xmlreader
using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings))
{
reader.close()
}
Run Code Online (Sandbox Code Playgroud)
但是,进入xmlreader的文件仍然处于使用范围之后的锁定状态,很奇怪,我xmlreader想要为我关闭文件流,不是吗?
感谢帮助.
我有一个MemoryStream由Stream类型参数传递的对象
(Stream在C#中是抽象类).
我想克隆他,并创建另一个MemoryStream对象与原始的当前位置的一面,并创建一个新XMLReader的,所以我将能够阅读其内容.
这就是我所做的,它不起作用(调试标有//* - >的行newReader有{None}值)
假设:你在一个方法内并有Stream currentStream参考.
var x = new XmlReaderSettings();
x.IgnoreWhitespace = true;
using (var newMemoryStream = new MemoryStream())
{
stream.CopyTo(newMemoryStream);
using (var newReader = XmlReader.Create(newMemoryStream,x)) //*
{
Doing some stuff...
}
}
Run Code Online (Sandbox Code Playgroud) 我试图XmlReader在一次传递中处理一个大的XML文档(使用a ),并使用一个反序列化其中的某些元素XmlSerializer.
下面是一些代码和一个微小的模拟XML文档,显示了我是如何尝试这样做的.
使用的基本原理
XmlReader: 1.我正在处理非常大的XML文档(10-250 MB),因此我不想加载到内存中.所以XmlDocument是不可能的.2.我想只提取某些元素.通常,我将能够忽略大多数其他内容.XmlReader似乎给了我一种跳过不相关内容的有效方法.3.我不提前知道是否有任何我能应付将出现的所有元素; 因此,我没有使用一堆Xpath/XQuery或LINQ到基于XML的查询,因为我只想对XML文件进行一次传递(由于它们的大小).
public class ElementOfInterest { }
…
var xml = @"<?xml version='1.0' encoding='utf-8' ?>
<Root xmlns:ex='urn:stakx:example'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<ElementOfInterest xsi:type='ex:ElementOfInterest' />
</Root>";
var reader = System.Xml.XmlReader.Create(new System.IO.StringReader(xml));
reader.ReadToFollowing("ElementOfInterest");
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(ElementOfInterest));
serializer.Deserialize(reader.ReadSubtree());
Run Code Online (Sandbox Code Playgroud)
最后一行代码抛出以下内部异常:
InvalidOperationException:"ex未定义名称空间前缀."
显然,XmlSerializer不识别属性值ex内的名称空间前缀xsi:type.
这只是我遇到的一个错误,但坦率地说,更大的问题是我不知道如何解决整个命名空间问题.我只是在寻找一种方便的方法来从XML文档中反序列化单个节点,但这似乎需要手动注册/管理命名空间,并以某种方式将它们转发XmlReader到XmlSerializer.
有人XmlReader可以通过指出我的代码中的错误,或通过显示替代方法来演示如何从使用的XML文档中反序列化单个节点吗?
XElement.Save 实际上做我需要的,但它启动文件:
<?xml version="1.0" encoding="utf-8"?>
Run Code Online (Sandbox Code Playgroud)
有办法防止这种情况吗?
在完成创建后,我应该使用其他类型,方法保存XElement吗?
或者我应该跳过那条线XmlReader.Read?因为这样做我觉得它更脆弱,因为我假设第一行总是这个xml声明.
实现这一目标的最简单方法是什么?
我正在尝试读取一个大的xml文件(大约40 MB),并使用此数据更新我的应用程序的数据库.
看来我使用XMLReader和simplexml_import_dom()在经过的时间/内存方面找到了一个很好的折衷方案但是我无法在名称中获得带冒号的属性值...例如<g:attr_name>.
如果我只是为每个"产品"节点使用$ reader-> read()函数,我可以将值作为$ reader-> value进行检索,但如果我展开()节点并使用$ doc-> importNode复制它,则此属性为忽略.
$reader = new XMLReader();
$reader->open(__XML_FILE__);
$doc = new DOMDocument;
while ($reader->read()) {
switch ($reader->nodeType) {
case (XMLREADER::ELEMENT):
if($reader->localName=="product"){
$node = simplexml_import_dom($doc->importNode($reader->expand(), true));
echo $node->attr_name."<br><br>";
$reader->next('product');
}
}
}
Run Code Online (Sandbox Code Playgroud)
可能我会想念一些事情......任何建议都会非常贴切!
谢谢.
当我使用XmlReader解析XML文件时,我会得到不同的结果,具体取决于XML文件是否格式正确(即使用换行符).
这是我正在使用的代码:
XmlReader reader = new XmlTextReader(xmlfile);
reader.MoveToContent();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == "entry")
{
Console.WriteLine(reader.ReadElementContentAsString());
}
break;
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在使用的XML内容是:
<xport><meta><columns>5</columns><legend><entry>AVERAGE:host:ed402b4d-71e7-4a8d-be29-ab6e54e955c8:memory_total_kib</entry><entry>AVERAGE:host:ed402b4d-71e7-4a8d-be29-ab6e54e955c8:memory_free_kib</entry><entry>AVERAGE:host:ed402b4d-71e7-4a8d-be29-ab6e54e955c8:xapi_memory_usage_kib</entry><entry>AVERAGE:host:ed402b4d-71e7-4a8d-be29-ab6e54e955c8:xapi_free_memory_kib</entry><entry>AVERAGE:host:ed402b4d-71e7-4a8d-be29-ab6e54e955c8:xapi_live_memory_kib</entry></legend></meta></xport>
Run Code Online (Sandbox Code Playgroud)
代码打印出的只有3行,当它真的应该打印5.我想我错过了一些东西,但是对我来说没有意义的是,当我不相同时,相同的代码会在同一个XML文件上产生不同的结果有白色空间.
抱歉打扰你这么简单的问题,但是我被困在这里一个小时:
我有一个看起来像这样的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<aaa xmlns="http://blabla.com/xmlschema/v1">
<bbb>
<ccc>Foo</ccc>
</bbb>
<ddd x="y" />
<ddd x="xx" />
<ddd x="z" />
</aaa>
Run Code Online (Sandbox Code Playgroud)
我试图像这样访问元素'ddd':
var doc = new XmlDocument();
doc.Load("example.xml");
foreach (XmlNode dddNode in doc.DocumentElement.SelectNodes("//ddd"))
{
// do something
Console.WriteLine(dddNode.Attributes["x"].Value);
}
Run Code Online (Sandbox Code Playgroud)
在运行时,跳过foreach循环,因为我没有从.SelectNodes方法返回任何节点.我在循环之前打破并查看了InnerXML,看起来很好,我还尝试了各种各样的XPath(比如"// bbb"或"/ aaa/ddd"),但只有"/"似乎没有返回空值.
这个确切的代码之前适用于我,现在它没有.我怀疑aaa标签中的命名空间声明,但我无法弄清楚为什么这会导致问题.或者......你能看到我可能遗失的任何东西吗?
我正在编写解析器,并尝试使用异常进行良好的错误处理.
以下示例代码:
<?php
$xml = <<<XML
<?xml version="1.0"?>
<rootElem>
XML;
$reader = new XMLReader();
$reader->xml($xml, null, LIBXML_NOERROR | LIBXML_NOWARNING);
$reader->read();
Run Code Online (Sandbox Code Playgroud)
发出:
PHP Warning: XMLReader::read(): An Error Occured while reading in /Users/evert/code/xml/errortest.php on line 11
PHP Stack trace:
PHP 1. {main}() /Users/evert/code/xml/errortest.php:0
PHP 2. XMLReader->read() /Users/evert/code/xml/errortest.php:11
Run Code Online (Sandbox Code Playgroud)
增加:
libxml_use_internal_errors(true);
Run Code Online (Sandbox Code Playgroud)
没有效果.
我的目标是稍后(使用libxml_get_errors())检查错误,并抛出异常.我觉得唯一的解决方案是使用silence(@)运算符,但这似乎是一个坏主意..
请注意,当我不传递LIBXML常量,也不使用时libxml_use_internal_errors,我会得到一个不同的错误,例如:
PHP Warning: XMLReader::read(): /Users/evert/code/xml/:2: parser error : Extra content at the end of the document in /Users/evert/code/xml/errortest.php on line 11
Run Code Online (Sandbox Code Playgroud)
这表明底层的libxml库确实压制了错误,但是在XMLReader中,无论如何都会抛出错误.
xmlreader ×10
c# ×7
xml ×4
.net ×3
php ×2
xelement ×2
domdocument ×1
encoding ×1
linq-to-xml ×1
memorystream ×1
simplexml ×1
stream ×1
utf-8 ×1
xml-parsing ×1