XmlReader正在跳过标签,我不知道为什么。如果执行下面的代码,则会看到ID 123和789被打印出来,表示456被跳过。如果运行使用1234的备用内存流,您只会看到123和456打印,这意味着1234和789被跳过。
这是主要部分。完整的代码如下。我用流创建一个XML阅读器,有一个while循环,我检查了想要的深度(因为节点不在深度0处)。据我了解,$posts = Post::whereHas('category', function($query) use($id) {
$query->where('parent_id', $id);
})->paginate(2);
{{ $posts->links() }}
@foreach ($posts as $post)
{{ $post->body }}
@endforeach
会读取XML,直到标签关闭为止,这正是我想要的。然后,我简单地打印出id值。很简单,不到十行代码
XElement.ReadFrom(root) as XElement
如果我在var root = XmlReader.Create(fs);
root.MoveToElement();
while (root.Read())
{
if (root.NodeType == XmlNodeType.EndElement || root.Depth != 1)
continue;
var el = XElement.ReadFrom(root) as XElement;
Console.WriteLine(el.Attribute("id").Value);
}
之间插入换行符,它将不会跳过标签,但感觉像是一个创可贴,而且我不确定我的输入是否在</node><node>
之后有换行符。
</node>
using System.Xml.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace nearMe
{
class Program
{
static void Main(string[] args)
{
using (var fs = new MemoryStream(UTF8Encoding.UTF8.GetBytes(@"<?xml version=""1.0"" encoding=""utf-8""?><test><node id=""123"">
<tag k=""amenity"" v=""fuel"" />
</node><node id=""456"">
<tag k=""name"" v=""B"" />
</node><node id=""789"">
<tag k=""amenity"" v=""test"" />
</node></test>")))
{
var root = XmlReader.Create(fs);
root.MoveToElement();
while (root.Read())
{
if (root.NodeType == XmlNodeType.EndElement || root.Depth != 1)
continue;
var el = XElement.ReadFrom(root) as XElement;
if (el == null)
continue;
if (el.Name != "node")
continue;
Console.WriteLine(el.Attribute("id").Value);
}
}
}
}
}
答案 0 :(得分:1)
您的错误在注释中指出了类似的问题:
调用[
XElement.ReadFrom
]会读取该元素并转到下一个元素,然后下一个[root.Read()
]会再次读取下一个元素。如果它们恰好具有相同的名称并且是连续的,那么您实际上会错过一个元素。 (pbz)
解决此问题的最简单方法是消除ReadFrom
并继续从读者那里获得价值:
while (root.Read())
{
if (root.NodeType != XmlNodeType.Element ||
root.Depth != 1 ||
root.Name != "node")
continue;
Console.WriteLine(root.GetAttribute("id"));
}
答案 1 :(得分:1)
using (var fs = new FileStream("test.xml", FileMode.Open, FileAccess.Read))
{
var test = XElement.Load(fs);
var nodes = test.XPathSelectElements("node[@id]");
foreach (var node in nodes)
{
Console.WriteLine(node.Attribute("id").Value);
}
}
答案 2 :(得分:0)
使用下面的代码。它不会跳过,而是使用xml阅读器。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using (var fs = new MemoryStream(UTF8Encoding.UTF8.GetBytes(@"<?xml version=""1.0"" encoding=""utf-8""?><test><node id=""123"">
<tag k=""amenity"" v=""fuel"" />
</node><node id=""456"">
<tag k=""name"" v=""B"" />
</node><node id=""789"">
<tag k=""amenity"" v=""test"" />
</node></test>")))
{
XmlReader reader = XmlReader.Create(fs);
while (!reader.EOF)
{
if(reader.Name != "node")
{
reader.ReadToFollowing("node");
}
if(!reader.EOF)
{
XElement node = (XElement)XElement.ReadFrom(reader);
int id = (int)node.Attribute("id");
Console.WriteLine(id.ToString());
}
}
}
Console.ReadLine();
}
}
}