konto usunięte

Temat: update xml'a

Panie i Panowie (a może sami Panowie? ;))

Mam taki problem posiadam taki o to xml


<?xml version="1.0" encoding="utf-8"?
<DesignConfiguration>
<Design name="jakaś_nazwa">
<SourceFolder>Jakas_wartosc_</SourceFolder>
<DestinationFolder>jakas_wartosc<DestinationFolder>
<CopyLookups>wartosc</CopyLookups>
<CopyImages>wartosc</CopyImages>
<SourceFolder>wartosc</SourceFolder>
<SourceFolder>wartosc</SourceFolder>
</Design>
<Design name="jakaś_nazwa2">
<SourceFolder>wartosc_2</SourceFolder>
<DestinationFolder>wartosc2<DestinationFolder>
<CopyLookups>wartosc2</CopyLookups>
<CopyImages>wartosc2</CopyImages>
<ImageSourceFolder>wartosc2</ImageSourceFolder>
<ImageDestinationFolder>wartosc2</ImageDestinationFolder>
</Design>
</DesignConfiguration>



public static void EditConfiguration (DesignConfiguration design)
{
XDocument configXml = XDocument.Load(configXMLFileName);



var updateData = configXml.Root.Elements("Design").Where(element => (String)element.Attribute("name") == design.DesignName).FirstOrDefault();
if (updateData != null)
{
var myElements = updateData.Elements(); //All the elements under the Design node
foreach (var item in myElements )
{
item.SetElementValue("SourceFolder", design.SourceFolder);
}
configXml.Save(configXMLFileName);
}
}


Owa metoda została mi podpowiedziana przez StackOverflow. Ta metoda jest odpowiedzialna za element edycyjny mojego prpogramu. Generalnie jako argument posiada obiekt DesignConfiguration który ma takie properties'y:

design.DesigName
design.SourceFolder
design.DestinationFolder
design.CopyLookups
design.CopyImages
design.ImageSourceFolder
design.ImageDestinationFolder

Chciałbym updateować tego XML'a na podstawie właściwosci DesignName elementy pod tym DesignName.

Próbowałem to googlować, ale wszędzie jest podane uzycie funkcji Descendants. Niestety w moim przypadku ona zwraca null czy jej użyję na DesignConfiguration czy na samym Design. Poprosiłem o pomoc na StackOverFlow i dostałem rozwiązanie jak prezentuję powyżej. Koleś mi pokazał jak zwrócić kolekcję. NIe byłoby w tym nic trudnego czy dziwnego tyle, że teraz nie wiem jak z tej kolekcji zaktualizować moje lementy tj.


<SourceFolder>wartosc_2</SourceFolder>
<DestinationFolder>wartosc2<DestinationFolder>
<CopyLookups>wartosc2</CopyLookups>
<CopyImages>wartosc2</CopyImages>
<ImageSourceFolder>wartosc2</ImageSourceFolder>
<ImageDestinationFolder>wartosc2</ImageDestinationFolder>


W powyższym przykładzie (moja funkcja) póki co próbuję dla testu aktualizować jeden element taka tam metoda prób i błędów no ale przez to dostaję następujący efekt (co jest chyba w miarę logiczne że tak jest).


<SourceFolder>C:\Test<SourceFolder>C:\Test</SourceFolder></SourceFolder>
<DestinationFolder>None<SourceFolder>C:\Test</SourceFolder></DestinationFolder>
<CopyLookups>True<SourceFolder>C:\Test</SourceFolder></CopyLookups>
<CopyImages>False<SourceFolder>C:\Test</SourceFolder></CopyImages>
<ImageSourceFolder>C:\Inetpub<SourceFolder>C:\Test</SourceFolder></ImageSourceFolder>
<ImageDesinationFolder>None<SourceFolder>C:\Test</SourceFolder></ImageDesinationFolder>


A to nie jest to co chcę osiągnąc chcę tam mieć nowe wartości z obiektu, który jest przekazywany do funkcji. Jakieś inne ciekawe podejście też chętnie zobaczę. Gneralnie ciekawe jest to, że mogę się dostać do elementów tylko poprzez użycie Róot a nie mogę przez Descendants. Próbowałem to też wygooglować dlaczego ta funkcja przychodzi pusta ale jakoś nie opdowiedziało to na moje pytania. Z góry dzięki za przebrnięcie przez to i za ewentualną pomoc, bo trochę mnie to frustruje...
Tomasz Poradowski

Tomasz Poradowski Specjalista od
wytwarzania
oprogramowania

Temat: update xml'a

Rafał K.:
Panie i Panowie (a może sami Panowie? ;))

Mam taki problem posiadam taki o to xml


var myElements = updateData.Elements(); //All the elements under the Design node
foreach (var item in myElements )
{
item.SetElementValue("SourceFolder", design.SourceFolder);
}

Skoro wywołujesz SetElementValue na każdym elemencie to dostajesz taki właśnie wynik - wywołaj
updateData.SetElementValue...
i powinno działać (dokumentacja do SetElementValue).
A to nie jest to co chcę osiągnąc chcę tam mieć nowe wartości z obiektu, który jest przekazywany do funkcji. Jakieś inne ciekawe podejście też chętnie zobaczę.

Stara poczciwa serializacja do XMLa :)

konto usunięte

Temat: update xml'a

Tego co proponujesz także próbowałem, zamiast mi zmienić wartośc w samym np source folder to mi po prosu dodaje cały element łącznie z Design ze zmienioną wartością.

Co do serializacji to coraz bardziej to rozważam....ale tak mnie naprowadziło to linq i tak brne w tyn Rafał K. edytował(a) ten post dnia 16.10.12 o godzinie 13:09
Tomasz Poradowski

Tomasz Poradowski Specjalista od
wytwarzania
oprogramowania

Temat: update xml'a

Rafał K.:
Tego co proponujesz także próbowałem, zamiast mi zmienić wartośc w samym np source folder to mi po prosu dodaje cały element łącznie z Design ze zmienioną wartością.

Jakby to powiedzieć... "u mnie działa" :) (musiałem co prawda poprawić XMLa, bo tagi były źle pozamykane, ale to właściwie tyle - reszta to prawie copy&paste z Twojego posta)


public class Program
{
public static void Main(string[] args)
{
var xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<DesignConfiguration>
<Design name=""jakaś_nazwa"">
<SourceFolder>Jakas_wartosc_</SourceFolder>
<DestinationFolder>jakas_wartosc</DestinationFolder>
<CopyLookups>wartosc</CopyLookups>
<CopyImages>wartosc</CopyImages>
<SourceFolder>wartosc</SourceFolder>
<SourceFolder>wartosc</SourceFolder>
</Design>
<Design name=""jakaś_nazwa2"">
<SourceFolder>wartosc_2</SourceFolder>
<DestinationFolder>wartosc2</DestinationFolder>
<CopyLookups>wartosc2</CopyLookups>
<CopyImages>wartosc2</CopyImages>
<ImageSourceFolder>wartosc2</ImageSourceFolder>
<ImageDestinationFolder>wartosc2</ImageDestinationFolder>
</Design>
</DesignConfiguration>";

Console.WriteLine(xml);
EditConfiguration(xml, "test1234");
Console.ReadLine();
}

public static void EditConfiguration(string xml, string newValue)
{
var configXml = XDocument.Parse(xml);
var updateData = configXml.Root.Elements("Design").Where(element => (String) element.Attribute("name") == "jakaś_nazwa").FirstOrDefault();
if (updateData != null)
{
updateData.SetElementValue("SourceFolder", newValue);
Console.WriteLine(configXml.ToString());
}
}
}

konto usunięte

Temat: update xml'a

Taaa u mnie też zadziałało poprosiłem kolegi o pomoc wychodzi na to że brakowało mi w ogóle drobiazgu małego i generalnie funkcja descendants nie wiedzieć czemu zadziałała ona chyba potrzebuje do tego zapytania linq czy coś takiego w sumie sam nie wiem....tak czy siak "dobrałem" się do tego takim zapytaniem



var test = (from s in configXml.Descendants("Design")
where s.Attribute("name").Value == design.DesignName select s).First();



Generalnie dobrym tropem szedłem zanim w ogóle zacząłem szukać tego i wypytywać na Stack'u. Drobiazg był taki,ze nie dopisywałem w tym select s (tak to jest być nowicjujsszem) i odstraszyło mnie od razu, że w części

where s.Attribute("name").Value == design.DesignName select s).First();


VS od razu mi podkreślał że coś mam nie tak a ja zamiast wpisać w niego nazwę swojego atrybutu(czyli dosłownie słowo name bo przecież tak się on nazywa) rozumiałem to jako wartość atrybutu i tak mi się to wszystko poprzestawiało. Dzięki za pomoc :)

ps. U mnie działa - klasyk ! :D



Wyślij zaproszenie do