我有一个非常奇怪的情况,我的SAX ContentHandler被XMLReader传递给错误的属性.正在解析的文档是UTF-8,XML属性中包含多字节字符.似乎发生的是每次调用我的处理程序时都会累积这些属性.因此,它们不是连续传递,而是连接到前一个节点的值.
以下是使用公共数据(维基百科)演示此示例的示例.
public class MyContentHandler extends org.xml.sax.helpers.DefaultHandler {
public static void main(String[] args) {
try {
org.xml.sax.XMLReader reader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
reader.setContentHandler(new MyContentHandler());
reader.parse("http://en.wikipedia.org/w/api.php?format=xml&action=query&list=allpages&apfilterredir=redirects&apdir=descending");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes attributes) {
if ("p".equals(qName)) {
String title = attributes.getValue("title");
System.out.println(title);
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新:这个完整的例子产生(对于粗俗的输出向任何广东话者道歉):
Run Code Online (Sandbox Code Playgroud)
有没有人知道发生了什么以及如何解决它?文档中的内容与我通过此代码段进行调试时发生的情况不符.
我有什么理由将XMLReader与SAXParser一起使用?我看到这种用法非常多:
sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
LoginContentHandler uch = new LoginContentHandler();
xr.setContentHandler(uch);
xr.parse(new InputSource(in));
Run Code Online (Sandbox Code Playgroud)
我总是这样使用解析器:
sp = spf.newSAXParser();
DefaultHandler dh = new LoginContentHandler();
sp.parse(in, dh);
Run Code Online (Sandbox Code Playgroud)
任何特殊原因?只是想知道因为我的方式更短,我真的不明白为什么我应该使用XMLReader.
我正在将一些在我的桌面上运行良好的Java代码移植到Android上.我有以下代码段:
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
// ...
XMLReader p = XMLReaderFactory.createXMLReader();
Run Code Online (Sandbox Code Playgroud)
在最后一行,我得到以下异常:
Can't create default XMLReader; is system property org.xml.sax.driver set?
Run Code Online (Sandbox Code Playgroud)
当我在桌面上测试代码时,它运行正常.为什么我在Android上遇到此异常,我该如何解决?谢谢!
我知道xmlreader和其他基于树的解析器(如simplexml和dom)之间的区别.但是xmlreader和xmlparser有什么区别?使用一个在另一个上有什么好处?
我需要解析相对较大的xml文件,联盟数据馈送大约100M.
我有一个大的XML文件(大约400MB),我需要确保在开始处理之前格式良好.
我尝试过的第一件事就是类似于下面的内容,这很棒,因为我可以发现XML是否格式不正确以及XML的哪些部分"糟糕"
$doc = simplexml_load_string($xmlstr);
if (!$doc) {
$errors = libxml_get_errors();
foreach ($errors as $error) {
echo display_xml_error($error);
}
libxml_clear_errors();
}
Run Code Online (Sandbox Code Playgroud)
还试过......
$doc->load( $tempFileName, LIBXML_DTDLOAD|LIBXML_DTDVALID )
Run Code Online (Sandbox Code Playgroud)
我用一个大约60MB的文件测试了这个,但是任何更大的东西(~400MB)都会导致一些对我来说是"新鲜杀手"的东西,在看起来像是30秒之后终止脚本.
我以为我可能需要增加脚本的内存,以便在处理60MB时找出峰值使用量,并相应地调整大小,并且还会关闭脚本时间限制以防万一.
set_time_limit(0);
ini_set('memory_limit', '512M');
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用,因为如果内存负载(即使是正确的术语?)一直很高,那么oom杀手似乎是一个linux的东西.
如果我能以某种方式加载xml,这将是很好的,因为我想这将减少内存负载,以便oom杀手不会坚持它的肥胖鼻子并杀死我的过程.
有没有人有任何验证大型XML文件和捕获错误形成错误的经验,我读过很多帖子都指向可能解决我问题的SAX和XMLReader.
更新 所以@chiborg几乎为我解决了这个问题...这个方法唯一的缺点就是我没有看到文件中的所有错误,只是第一个失败,我认为这是有意义的,因为我认为它无法解析失败的第一个点.
当使用simplexml时...它能够捕获文件中的大部分问题并在最后向我展示这很好.
我在解析具有 utf-16 编码的 XML 时遇到问题,但它与 utf-8 完美配合。
任何人都可以帮助我解决这个问题吗?
我收到以下错误:
System.Web.HttpUnhandledException' was thrown.
System.Xml.XmlException: There is no Unicode byte order mark.
Cannot switch to Unicode
XML 标头:
<?xml version="1.0" encoding="utf-16"?>
<RiskAssessmentRequestValue xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Run Code Online (Sandbox Code Playgroud)
C# 代码隐藏:
rptTransformedXml.DataSource = parser.ExtractData(xml);
rptTransformedXml.DataBind();
public List<XmlDataExtract> ExtractData(string xml)
{
MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(xml));
return ExtractData(stream);
}
public List<XmlDataExtract> ExtractData(Stream xmlStream)
{
XmlReaderSettings settings = new XmlReaderSettings
{
IgnoreComments = true,
IgnoreWhitespace = true,
CloseInput = true
};
XmlReader reader = XmlReader.Create(xmlStream, settings);
XmlPathBuilder pathBuilder = …Run Code Online (Sandbox Code Playgroud) 我有一个非常大的XML文件(数百万条记录).由于速度和内存限制,我打算使用XMLReader/ XMLWriter.
我需要读取文件,获取一条记录,更改其属性,最后再次保存XML.
为了测试,我创建了一个XML文件,并使用以下行将一些记录写入其中:
$doc = new XMLWriter();
$doc->openURI($xmlFile);
$doc->startDocument('1.0','UTF-8');
$doc->setIndent(4);
$doc->startElement('DBOS');
for($r=0;$r<10; $r++){
$doc->startElement('ITEMS');
for($i=0;$i<5; $i++){
$doc->startElement('ITEM');
$doc->writeAttribute('id', $r.'-'.$i);
$doc->endElement();
}
$doc->endElement();
}
$doc->endElement();
$doc->endDocument();
$doc->flush();
Run Code Online (Sandbox Code Playgroud)
我用这个再读一遍:
$reader = new XMLReader();
if (!$reader->open($xmlFile)){
die("Failed to open 'data.xml'");
}
while($reader->read()){
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'ITEMS') {
$node = $reader->expand();
$items = $node->childNodes;
foreach ($items as $ik => $itm ){
print $itm->textContent.'<br/>';
// how to change the ID Attribute of a Node (DomNode) and save …Run Code Online (Sandbox Code Playgroud) 有没有办法阻止 .NET 的XmlReader类在读取内容时将 XML 实体扩展为其值?
例如,假设使用以下 XML 作为输入:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE author PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML" "http://www.oasis-open.org/docbook/xmlcharent/0.3/iso-lat1.ent" >
<author>á</author>
Run Code Online (Sandbox Code Playgroud)
我们假设不可能达到扩展急性实体所需的外部 OASIS DTD。我希望读者按顺序读取author 元素,然后是type 的aacute 节点EntityReference,最后是author end 元素,而不会抛出任何错误。我怎样才能实现这个目标?
更新:我还想防止字符实体的扩展,例如á.
如果数据在一行上
index=int.Parse(logDataReader.ReadElementContentAsString());
,则
value=double.Parse(logDataReader.ReadElementContentAsString(),
使光标向前移动。如果我取消这些调用,我会看到它在调试中循环了 6 次。
在下面<data>的第一个 ( <logData id="Bravo">) 中只读取了3 个(并且它们是错误的,因为该值用于下一个索引)。在第二个 ( <logData id="Bravo">) 上,所有内容<data>都已读取。
由于该文件是动态创建的(由 XMLwriter),因此无法编辑 xml 并插入换行符。该NewLineChars设置是换行。从 XMLwriter 开始,它实际上只是一行 - 我将它分解以找出它在哪里中断。在浏览器中它正确显示。
如何解决这个问题?
这是我的 XML:
<?xml version="1.0" encoding="utf-8"?>
<log>
<logData id="Alpha">
<data><index>100</index><value>150</value></data>
<data><index>110</index><value>750</value></data>
<data><index>120</index><value>750</value></data>
<data><index>130</index><value>150</value></data>
<data><index>140</index><value>0</value></data>
<data><index>150</index><value>222</value></data>
</logData>
<logData id="Bravo">
<data>
<index>100</index>
<value>25</value>
</data>
<data>
<index>110</index>
<value>11</value>
</data>
<data>
<index>120</index>
<value>1</value>
</data>
<data>
<index>130</index>
<value>25</value></data>
<data>
<index>140</index>
<value>0</value>
</data>
<data>
<index>150</index>
<value>1</value>
</data>
</logData>
</log>
Run Code Online (Sandbox Code Playgroud)
还有我的代码:
static void Main(string[] …Run Code Online (Sandbox Code Playgroud) 我在 .Net 4.5 中升级了我的旧应用程序。有一些过时的方法警告我非常想解决它们。过时的方法之一是 XmlValidatingReader。在互联网上查了一下,发现XmlReaderSettings是 XmlValidatingReader 的潜在替代品。
// ==old code==
Hashtable _SchemasCache = new Hashtable();
XmlReader xmlReader = new XmlTextReader(xmlStream);
XmlValidatingReader validatingReader = new XmlValidatingReader(xmlReader);
validatingReader.Schemas.Add(root.Namespace, schemaLocation); // both parametres are string. No error
_SchemasCache.Add(schemaLocation, validatingReader.Schemas);
// ==new code==
var schemaLocation = "res://somepath/Messages.xsd";
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(root.Namespace, schemaLocation); // this line gives error
_SchemasCache.Add(schemaLocation, settings.Schemas);
Run Code Online (Sandbox Code Playgroud)
旧代码没有给出任何错误,但新代码给出了一个错误,The URI prefix is not recognized.我找不到 的这种行为的原因settings.Schemas.Add(),因为它与XmlValidatingReader. 有人能帮忙吗?
编辑:这里schemaLocation 的值是“res://somepath/Messages.xsd”。因为 schemaLocation没有Http: …