我在循环浏览XML文档的节点时遇到了困难。 我有一个具有以下层次结构的文档:
<?xml version="1.0" encoding="UTF-8"?>
<TEMPONDERZOEK xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<TRIES>3</TRIES>
<RESULTATEN>
<INSTRUMENT>
<INSTRUMENT_CODE>SPOTCHEM EZ</INSTRUMENT_CODE>
<TEST_CODE>0</TEST_CODE>
<VLAG>1</VLAG>
<ANALYSES>
<ANALYSE>
<AFKORTING>BUN</AFKORTING>
<WAARDE>23.7</WAARDE>
<EENHEID>MMOL/L</EENHEID>
</ANALYSE>
<ANALYSE>
<AFKORTING>GLU</AFKORTING>
<WAARDE>15.0</WAARDE>
<EENHEID>MMOL/L</EENHEID>
</ANALYSE>
</ANALYSES>
</INSTRUMENT>
<INSTRUMENT>
<INSTRUMENT_CODE>SPOTCHEM EL</INSTRUMENT_CODE>
<TEST_CODE>1</TEST_CODE>
<VLAG>1</VLAG>
<ANALYSES>
<ANALYSE>
<AFKORTING>Na</AFKORTING>
<WAARDE> 152</WAARDE>
<EENHEID>mmol/L</EENHEID>
</ANALYSE>
<ANALYSE>
<AFKORTING>K</AFKORTING>
<WAARDE> 4.4</WAARDE>
<EENHEID>mmol/L</EENHEID>
</ANALYSE>
</ANALYSES>
</INSTRUMENT>
</RESULTATEN>
</TEMPONDERZOEK>
我编写了以下C#代码来遍历文档:
// Get all fraudulent XML files
string[] fraudulentsArray = Directory.GetFiles(@"tempXML\fraudulent", "temp_*.xml");
// Iterate through every XML file that has been collected
foreach (var x in fraudulentsArray)
{
XmlDocument xml = new XmlDocument();
xml.Load(x);
// Get the first parent node
XmlNode resultaten = xml.SelectSingleNode("//RESULTATEN");
// Get all the INSTRUMENT nodes in RESULTATEN
var instrumentNodes = resultaten.SelectNodes("//INSTRUMENT");
// Loop through the instrument nodes
for (int i = 0; i < instrumentNodes.Count; i++)
{
// Get the values from nodes inside parent node INSTRUMENT and store them
xmlanalyse.INSTRUMENT_CODE = instrumentNodes[i].ChildNodes[0].InnerText;
xmlanalyse.TEST_CODE = instrumentNodes[i].ChildNodes[1].InnerText.ToInt();
xmlanalyse.VLAG = instrumentNodes[i].ChildNodes[2].InnerText.ToInt();
// Get the ANALYSES parent node
XmlNode analyses = instrumentNodes[i].SelectSingleNode("//ANALYSES");
// Get all the ANALYSE nodes in parent node ANALYSES
var analysesNodes = analyses.SelectNodes("//ANALYSE");
// Loop through the ANALYSE nodes
for (int j = 0; j < analysesNodes.Count; j++)
{
// Store them..
ANALYSE tempresultaat = new ANALYSE();
tempresultaat.AFKORTING = analysesNodes[j].ChildNodes[0].InnerText;
tempresultaat.WAARDE = analysesNodes[j].ChildNodes[1].InnerText;
tempresultaat.EENHEID = analysesNodes[j].ChildNodes[2].InnerText;
xmlanalyse.ANALYSES.Add(tempresultaat);
}
onderzoek.RESULTATEN.Add(xmlanalyse);
}
}
我对此循环的问题在于它没有区分INSTRUMENT节点。结果是在第一个循环中,我从第一个INSTRUMENT节点获取ANALYZE的所有值,但我也从第二个INSTRUMENT节点获得ANALYZE的值。这也发生在第二个循环中。
答案 0 :(得分:1)
您需要在XPATH表达式上指明当前上下文(只是.
):
var instrumentNodes = resultaten.SelectNodes(".//INSTRUMENT");
var analyses = instrumentNodes[i].SelectSingleNode(".//ANALYSES");
var analysesNodes = analyses.SelectNodes(".//ANALYSE");
理想情况下,您可以删除所有//
并使用默认的当前上下文:
foreach (XmlElement instrument in xml.SelectNodes("//INSTRUMENT"))
{
Console.WriteLine(instrument.SelectSingleNode("INSTRUMENT_CODE").InnerText);
foreach (XmlElement analyse in instrument.SelectNodes("ANALYSES/ANALYSE"))
{
Console.WriteLine(analyse.SelectSingleNode("AFKORTING").InnerText);
}
}
另一个建议是避免使用ChildNodes[n]
语法,因为如果XML文件发生更改,代码将会中断。考虑上面的“AFKORTING”示例。
您是否尝试将XML文件转换为业务对象?你试过deserialize吗?