2016-02-14 106 views
1

我有一個看起來像2 XML文檔:查找和節點的替換內容

  1. 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> 
    
  2. 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> 
    

我是什麼試圖做的是從d中的元數據節點獲取文本oc1,在doc2中的子字段代碼=「x」節點中搜索它,如果它存在,則獲取相同記錄節點的子字段代碼=「e」文本,並用它替換相應的doc1 // collection/name節點文本。

現在我用下面的代碼

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; 
        } 

       } 


     } 

但它顯示「未將對象引用設置到對象的實例」錯誤的第二個消息框。

+0

我更新我的回答 – zx485

回答

1

您選擇所有subfield節點在你的第一個XPath表達式

//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()); 
    ... 
} 
+0

是的,謝謝,我想通這就是爲什麼的SelectSingleNode返回null。任何建議如何做到這一點簡單? – mmdfan