Przetwarzanie dokumentów XML

0

Witam. Aplikacja na wejściu otrzymuje plik XML w postaci:

 <?xml version="1.0" encoding="windows-1250"?>
<ROOT>
	<RECORDSET1>
		<RECORD USR="[email protected]" />
	</RECORDSET1>
	<RECORDSET2>
		<RECORD atr="..." />
	</RECORDSET2>
	<RECORDSET3>
		<RECORD atr="..." />
	</RECORDSET3>
</ROOT>
  1. Interesuje nas odczyt atrybutu USR. Zawsze będzie to w gałęzi ROOT/RECORDSET1/RECORD. Napisałem taki kod:
string filename = ""; // to mamy dane
string usrName; //tę zmienną chcemy wypełnić danymi.
        
XPathDocument iDocument = new XPathDocument(filename);
XPathNavigator navigator = iDocument.CreateNavigator();
XPathNodeIterator nodeIterator = navigator.Select("/ROOT/RECORDSET1/RECORD");

nodeIterator.MoveNext();
XPathNavigator node = nodeIterator.Current;
                      
smtpServer = node.GetAttribute("USR", "");

Działa.

W toku działania aplikacji muszę się jeszcze parę razy odwoływać do konkretnego argumentu w konkretnej gałęzi dokumentu. Za każdym razem jest ona jednoznacznie i dokładnie określona.

Mogę to oczywiście opakować w funkcję, nie mogę jednak oprzeć się wrażeniu, że strzelam z armaty do muchy. Da się jakoś prościej (i krócej!) dobrać do interesującej nas wartości?

  1. Wydaje mi się (chociaż nie dam sobie za to uciąć nogi), że powyższy kod po zakończeniu wciąż trzyma otwarty plik. Obiekt XPathDocument nie ma metody close() ani żadnej podobnej, a po jego zakończeniu pliku nie da się usunąć (dopóki działa aplikacja)...

  2. W innym miejscu - mam wczytany ten plik do obiektu XmlDocument:

XmlTextReader iFile = new XmlTextReader(oldFileName);
XmlTextWriter oFile = new XmlTextWriter(newFileName);

XmlDocument document = new XmlDocument();
document.Load(iFile);

//jakieś-tam nieporadne przekształcenia na dokumencie

document.WriteTo(oFile);

oFile.Flush();
iFile.Close();
oFile.Close();

Też działa, ale dokument wynikowy zapisywany jest w utf-16, ale z pozostawioną oryginalną deklaracją kodowania. Mogę co prawda po zakończeniu tego użyć streamreadera/writera, otworzyć plik ponownie, podmienić pierwszą linijkę i zapisać... Ale to już będzie parodia.
Jak, mając wczytany plik do obiektu XmlDocument, zmienić w nim początkową deklarację?

Dziękuję za odpowiedzi i pozdrawiam.

0
  1. Nie bardzo wiem ,co masz na myśli. Poczytaj sobie o xpath-ie ,można dzięki niemu bardzo łatwo przechodzić po nodach. Dla przykładu jak chcesz wszystkie rekordy z atrybutem USR to masz po prostu : "//Record[@USR]"

  2. XpathDocument jest tylko do odczytu więc wczytuje z pliku do pamięci, a następnie zamyka strumień. Możesz usunąć ten plik albo go z edytować ręcznie i XpathDocument dalej będzie działał ,ale na starej kopii.

3)Nie jestem pewien czy to o to chodzi, ale może skorzystaj z document.CreateXmlDeclaration() ??

0
  1. Może przy użyciu tych klas będzie wyglądało prościej.
using System.Xml;
using System.Xml.Linq;
using System.IO;

if (File.Exists("Dane.xml"))
{
    XDocument xDocument = XDocument.Load("Dane.xml");
    XElement xRoot = xDocument.Element("ROOT");
    XElement xElement = xRoot.Element("RECORDSET1").Element("RECORD");
    string USR = xElement.Attribute("USR").Value;
}

W skrócie

string USR = XDocument.Load("Dane.xml").Element("ROOT").Element("RECORDSET1").Element("RECORD").Attribute("USR").Value;

1 użytkowników online, w tym zalogowanych: 0, gości: 1