我有2个XML文档,如下所示:
DOC1
<?xml version="1.0" encoding="UTF-8"?>
<import>
<collection>
<name>II_14714_1889</name>
<metadata>512143197.xml</metadata>
</collection>
<collection>
<name>II_14714_1884</name>
<metadata>512142173.xml</metadata>
</collection>
<collection>
<name>II_14714_1886</name>
<metadata>512142685.xml</metadata>
</collection>
</import>
DOC2
<?xml version="1.0" encoding="UTF-8"?>
<collection>
<record>
<datafield tag="000">
<subfield code="x">512143197</subfield>
<subfield code="r">...</subfield>
</datafield>
<datafield tag="200">
<subfield code="e">1989</subfield>
</datafield>
</record>
<record>
<datafield tag="000">
<subfield code="x">512143180</subfield>
<subfield code="r">...</subfield>
</datafield>
<datafield tag="200">
<subfield code="e">1970</subfield>
</datafield>
</record>
<record>
<datafield tag="000">
<subfield code="x">512143198</subfield>
<subfield code="r">...</subfield>
</datafield>
<datafield tag="200">
<subfield code="e">1990</subfield>
</datafield>
</record>
</collection>
我要做的是从doc1中的元数据节点获取文本,在doc2中的子字段代码中搜索它=&#34; x&#34;节点,如果它在那里得到子字段代码=&#34; e&#34;同一记录节点的文本,并用它替换相应的doc1 //集合/名称节点文本。
目前我正在使用以下代码
foreach (XmlNode xmlMetadata in doc1.DocumentElement.SelectNodes("//collection/metadata"))
{
string id = xmlMetadata.InnerText.ToString();
string resultString = Regex.Match(id, @"\d\d\d\d+").Value;
MessageBox.Show(resultString);
foreach (XmlNode xmlSubfield in doc2.SelectNodes("//record/datafield[@tag='000']/subfield[@code='x']"))
{
string subfield = xmlSubfield.InnerText.ToString();
if (subfield == resultString)
{
MessageBox.Show(xmlSubfield.SelectSingleNode("../datafield[@tag='200']/subfield[@code='e']").InnerText.ToString());
string year = xmlSubfield.SelectSingleNode("../datafield[@tag='200']/subfield[@code='e']").InnerText.ToString();
year = Regex.Match(godina, @"\d\d\d\d").Value;
doc2.SelectSingleNode("../datafield[@tag='200']/subfield[@code='e']").InnerText = godina;
}
}
}
但它显示&#34;对象引用未设置为对象的实例&#34;第二个MessageBox出错。
答案 0 :(得分:1)
您正在选择第一个XPath表达式中的所有subfield
个节点
//record/datafield[@tag='000']/subfield[@code='x']
因此,您必须在开头添加另一个../
到MessageBox.Show
的XPath表达式,以达到记录节点级别。
MessageBox.Show(xmlSubfield.SelectSingleNode("../../datafield[@tag='200']/subfield[@code='e']").InnerText.ToString());
^^^ here
编辑:实现这一目标的更简单方法是
foreach (XmlNode xmlSubfield in doc2.SelectNodes("//record[datafield[@tag='000']/subfield[@code='x'] = '"+resultString+"']/datafield[@tag='200']/subfield[@code='e']"))
{
MessageBox.Show(xmlSubfield.InnerText.ToString());
...
}