XML:
<InformationTuples>
<InformationTuple>
<Name>documentClass</Name>
<value format="" valueset="{rechnung}" originalValue="Rechnung" start="0" end="0" LD="0" doc="C:\b4enviam-service-test\inputDir\031a0933-2616-4d8e-8a79-56746ae0e160/Invoice_51029062.pdf">Rechnung</value>
<EntityType>Class</EntityType>
<state>New </state>
<need>Mandatory </need>
<extractionmethod>
</extractionmethod>
<weight>1</weight>
<precondition type="optional">All</precondition>
</InformationTuple>
<InformationTuple>
<Name>SAPNr.</Name>
<value format="" valueset="" originalValue="4352020616" start="0" end="0" LD="0" doc="C:\b4enviam-service-test\inputDir\031a0933-2616-4d8e-8a79-56746ae0e160/Invoice_51029062.pdf">4352020616</value>
<EntityType>KB.GTInovice</EntityType>
<state>New </state>
<need>Mandatory </need>
<extractionmethod>
</extractionmethod>
<weight>1</weight>
<precondition type="optional">all</precondition>
</InformationTuple>
<InformationTuple>
<Name>GT-Invoice</Name>
<value format="" valueset="" originalValue="" start="0" end="0" LD="0" doc="">
</value>
<EntityType>KB.GTInovice</EntityType>
<state>New </state>
<need>Mandatory </need>
<extractionmethod>
</extractionmethod>
<weight>1</weight>
<precondition type="optional">all</precondition>
</InformationTuple>
</InformationTuples>
C#
reader.ReadToFollowing("InformationTuple");
reader2.ReadToFollowing("InformationTuple");
do
{
subtree = reader2.ReadSubtree();
subtree.ReadToFollowing("Name");
Debug.WriteLine(subtree.ReadElementContentAsString());
reader2.ReadToNextSibling("InfromationTuple");
} while (reader.ReadToNextSibling("InformationTuple"))
我现在尝试使用c#从XML中提取多个子节点的数据但是没有成功。我尝试了多个代码片段但无法提取数据。
就像我必须提取三个信息元组中给出的数据一样,但XMLreader中给出的函数无法正常工作,读取器指针在单循环迭代后无法移动(无法移动到第二个InformationTuple),即使我尝试了两个不同的读取器指针但是它现在给予例外。
需要一些帮助, 谢谢
答案 0 :(得分:1)
您可以使用以下方法阅读每个<Name>
元素中的<InformationTuple>
元素:
static IEnumerable<string> ReadNames(XmlReader reader)
{
while (reader.ReadToFollowing("InformationTuple"))
{
using (var subReader = reader.ReadSubtree())
{
subReader.ReadToFollowing("Name");
var name = subReader.ReadElementContentAsString();
yield return name;
}
}
}
一些注意事项:
完成后,您不会关闭(或处置)ReadSubtree()
子树阅读器。来自docs:
在新阅读器关闭之前,您不应对原始阅读器执行任何操作。此操作不受支持,可能导致不可预测的行为。
因此,在推进外部阅读器之前,必须关闭或处置此嵌套阅读器。
您在开始时拨打过多reader.ReadToFollowing("InformationTuple");
。也许你打算做reader.ReadToFollowing("InformationTuples");
?
如果您只想阅读每个<Name>
容器中每个<InformationTuple>
元素的<InformationTuples>
元素,您可以执行以下操作:
static IEnumerable<string> ReadNestedNames(XmlReader reader)
{
foreach (var subReader in reader.ReadSubtrees("InformationTuples").SelectMany(r => r.ReadSubtrees("InformationTuple")))
{
subReader.ReadToFollowing("Name");
var name = subReader.ReadElementContentAsString();
yield return name;
}
}
使用扩展方法:
public static class XmlReaderExtensions
{
public static IEnumerable<XmlReader> ReadSubtrees(this XmlReader reader, string name)
{
while (reader.ReadToFollowing(name))
{
using (var subReader = reader.ReadSubtree())
yield return subReader;
}
}
}
答案 1 :(得分:0)
下面的代码我经常使用,不会产生任何错误。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
while (!reader.EOF)
{
if (reader.Name != "InformationTuple")
{
reader.ReadToFollowing("InformationTuple");
}
if (!reader.EOF)
{
XElement subtree = (XElement)XElement.ReadFrom(reader);
Info.info.Add(new Info() { state = (string)subtree.Element("state"), weight = (int)subtree.Element("weight") });
}
}
}
}
public class Info
{
public static List<Info> info = new List<Info>();
public string state { get; set; }
public int weight { get; set; }
}
}