2016-07-18 3 views
1

Я пытаюсь изменить XML-документ, который мы не создали изначально. Snippit из XML ниже:C# XML дочерний узел аналогичного родного брата

<DEALS> 
    <DEAL> 
    <LOANS> 
     <LOAN LoanRoleType="SubjectLoan"> 
     <BUYDOWN> 
      <BUYDOWN_RULE> 
      <BuydownInformation>0</BuydownInformation> 
      </BUYDOWN_RULE> 
     </BUYDOWN> 
     </LOAN> 
     <LOAN LoanRoleType="SubjectLoan"> 
     <LOAN_IDENTIFIERS> 
      <LOAN_IDENTIFIER> 
      ... 
      </LOAN_IDENTIFIER> 
      <LOAN_IDENTIFIER> 
      <SellerLoanIdentifier>1234567890</SellerLoanIdentifier> 
      </LOAN_IDENTIFIER> 
     </LOAN_IDENTIFIERS> 
     </LOAN> 
    </LOANS> 
    </DEAL> 
    <DEAL> 
    ...Same format as above... 
    </DEAL> 
</DEALS> 

Первый LOAN элемент каждого DEAL никогда не будет содержать LOAN_IDENTIFIERS. Мне нужно получить InnerText SellerLoanIdentifier, а затем поместить его в <BuydownInformation> первого элемента LOAN. Я пробовал вложенные циклы и, похоже, не мог отличить два элемента LOAN (второй цикл даже не видит элементы LOAN). Я думаю, что это также связано с тем фактом, что они оба несут один и тот же атрибут, но не могут найти что-либо в Интернете до этого момента, чтобы помочь.

XmlDocument xmlExport = new XmlDocument(); 
xmlExport.Load(fileDestination); 

string loanNumber = ""; 

XmlNodeList loan_XMLDeals = xmlExport.GetElementsByTagName("DEAL"); 
Logger.WriteDebug("Found " + loan_XMLDeals.Count + " Deals"); 
foreach (XmlNode loan_XMLDeal in loan_XMLDeals) 
{ 
    XmlNodeList loan_XMLLoans = loan_XMLDeal.SelectNodes("LOAN"); 
    Logger.WriteDebug("Found " + loan_XMLLoans.Count + " Loan categories"); 
    foreach (XmlNode loan_XMLCategory in loan_XMLLoans) 
    { 
     if(loan_XMLCategory.SelectSingleNode("SellerLoanIdentifier") != null) 
     { 
      loanNumber = loan_XMLCategory.SelectSingleNode("SellerLoanIdentifier").ToString(); 
      Logger.WriteDebug("Got loan number " + loanNumber); 
     } 
    } 
} 
+0

Не помещайте Google Искать в названии вашего вопроса, если это не то, что вы на самом деле просят. Если это так, вам нужно уточнить немного больше в своем сообщении. –

+0

Итак, ровно 2 'LOAN' элемента на' DEAL', скопируйте (вложенное) значение 'SellerLoanIdentifier' второго элемента' LOAN' в (вложенный) 'BuydownInformation' первого элемента' LOAN'? Верный? – spender

+0

Да @spender это правильно. – cardmstr

ответ

1

Это становится намного проще с linq в xml. Это означает, что вы удалите (старый) XmlDocument и замените его на более дружелюбный XDocument.

Вместо поиска всего документа для цели вам необходимо начать с контекста, где вы нашли SellerLoanIdentifier. Вы можете вернуться к элементу LOAN, найти его предыдущего родного брата, затем выполнить поиск, который для BuydownInformation. Поскольку это все включено в одну запись LOANS, вы можете быть уверены, что настроите правильный элемент.

Итак ...

var doc = XDocument.Load(fileDestination); 
//we're going to select a sequence of items that contain 2 values... 
//the element we want to change and the value we want to store in it 
var changes= doc.Root 
       .Elements("DEAL") 
       .Descendants("SellerLoanIdentifier") 
       //from each SellerLoanIdentifier in DEAL elements 
       .Select(e => new{ 
        //the node we want to change 
        //in this case we get the parent LOAN 
        //element, take the last of the elements 
        //that precede it in the document 
        //(e.g. the previous sibling which 
        //contains the target node) 
        //and find in it a descendant of type 
        //BuydownInformation 
        nodeToChange = e.Ancestors("LOAN") 
            .Single() 
            .ElementsBeforeSelf() 
            .Last() 
            .Descendants("BuydownInformation") 
            .Single(), 
        //the string value of the current element 
        val = (string)e 
       }); 
//then apply the changes back to the document 
foreach(var change in changes) 
{ 
    change.nodeToChange.Value = change.val; 
} 
var newXmlString = doc.ToString(); 

Есть предположения здесь о форме ваших данных, которые не могут держать так, но это должно быть относительно легко изменить.

0

Попробуйте этот простой XML Linq код

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) 
     { 
      XDocument doc = XDocument.Load(FILENAME); 
      List<XElement> loans = doc.Descendants("LOANS").ToList(); 
      foreach (XElement loan in loans) 
      { 
       string sellerLoanIdentifier = (string)loan.Descendants("SellerLoanIdentifier").FirstOrDefault(); 
       XElement buydownInformation = loan.Descendants("BuydownInformation").FirstOrDefault(); 
       buydownInformation.Value = sellerLoanIdentifier; 
      } 
     } 
    } 
} 
Смежные вопросы