[inne]Wyrażenia regularne, xml

0

Witam,
Próbuje sformułować wyrażenie od wyciagniecia odpowiednich rzeczy z zml a mianowicie zawartości.
lecz nawet najprostsze wyrażenie mi nie działa.
<(.)>(.)<.\1>

chodzi mi o to bym dostał:
<breakfast_menu>...</breakfast_menu>
Prosze o pomoc

testuje na danych :

<breakfast_menu>
<food>
<name>
Belgian Waffles
</name>
<price>
$5.95
</price>
<description>
two of our famous Belgian Waffles with plenty of real maple syrup
</description>
<calories>
650
</calories>
</food>
<food>
<name>
Strawberry Belgian Waffles
</name>
<price>
$7.95
</price>
<description>
light Belgian waffles covered with strawberries and whipped cream
</description>
<calories>
900
</calories>
</food>
<food>
<name>
Berry-Berry Belgian Waffles
</name>
<price>
$8.95
</price>
<description>
light Belgian waffles covered with an assortment of fresh berries and whipped cream
</description>
<calories>
900
</calories>
</food>
<food>
<name>
French Toast
</name>
<price>
$4.50
</price>
<description>
thick slices made from our homemade sourdough bread
</description>
<calories>
600
</calories>
</food>
<food>
<name>
Homestyle Breakfast
</name>
<price>
$6.95
</price>
<description>
two eggs, bacon or sausage, toast, and our ever-popular hash browns
</description>
<calories>
950
</calories>
</food>
</breakfast_menu>
0

Nie przetwarzaj XML za pomocą wyrażeń regularnych. Użyj pełnego parsera XML.

0

Potrzebuje tego dość szybko i sadze ze jedno wyrażenie uratowało by mnie. Za to nauka obsługi parsera zajeła by mi z 2 dni bo nie widze tutorialu po polsku

0

Za to nauka wyrazen regularnych na tyle, zeby dalo sie wyciagac wartosci zagniezdzone zajmie Ci tydzien albo dwa. Wez jezyk, gdzie sa dostepne na tacy klasy do parsowania (np. c#) i bedzie naprawde szybciej.

0

muszę to napisać w C

0

To uzyj stosu i prostego przechodzenia/przeszukiwania po tekscie.

0
  • zakladam, ze Twoj silnik regexp obsluguje ten backreference \1

oryginalne <(.)>(.)<.\1> jest prawie ok
powinienes byl uzyc klasy znakow wykluczajacej otwarcie taga/zamkniecie i/lub lapania niezachlannego

samo: <([>]+)>([<]+)</\1>
absolutnie wystarczy do takiego xml'a, jezeli:

  • Twoje tagi NIE POSIADAJA atrubutow
  • zawartosc tekstowa nigdy nie jest pusta
  • tagi sa 'ciasne' i nie maja bialych znakow w glupich miejscach
    No i oczywiscie, musisz startowac z recznie ustalanej pozycji w ciagu, gdyz tenże złapie tylko jeden tag, najblizszy. O orientowanie sie w ktorym miejscu drzewa jestes - tez musisz sam zadbac, gdyz regexpem takim jedynie odczytasz ze name=, albo price=

btw. a moze jakis xerces albo msxml?

0

Dzięki wielkie za odp.

Właściwie chodziło mi o wyłuskanie rekurencyjnie. Tzn wyciągnąć najpierw zawartość elementu root i później zagłębiać się.
Lecz niestety właśnie sobie uświadomiłem ze może mój silnik nie obsługiwać wstecznej referencji bo w programiku wyrażenie się nie sprawdza a na stronie działa.

Co do parserów xml z chęcią bym ów takiego użył ale mama trochę mało czasu a przebijanie się przez dokumentacje w j.angielskim trochę mi zajmie. Projekt jest pisany w C wiec próbowałem parsera napisanej w C: expat. Lecz jakos nie wychodziło mi to. Załączam fragment kodu.

	regex_t rx;
	char *pat = "<([^>]+)>([^<]+)<\/\1>";
	char *str2;
	regmatch_t match [255];
	int i;
	str2 = fileToString("simple.xml");
	//fromJason(str2, NULL);
	printf("%s", str2);

	regcomp (&rx, pat, 0);
	regexec (&rx, str2, 255, match, 0);

	for (i=0; i<1; ++i)
	{
		printf ("Wynik %i do %i: `%.*s'\n",
			match[i].rm_so, match[i].rm_eo,
			match[i].rm_eo-match[i].rm_so,
			&str2[match[i].rm_so]);
	}
char* fileToString(char fileName[]){
	char *returnString;
	long dlugosc;
	FILE *hFile;
	if((hFile = fopen(fileName, "r")) == NULL){
		perror("Błąd przy otwieraniu pliku\n");
		return 0;
	}
	fseek (hFile, 0, SEEK_END); /* ustawiamy wskaźnik na koniec pliku */
	dlugosc = ftell (hFile);
	fseek (hFile, 0, SEEK_SET);
	printf("dlugosc: %d", dlugosc);
	returnString = (char*) malloc(sizeof(char) * (++dlugosc));
	fread(returnString, 1, dlugosc, hFile);
	return returnString;
}

Pozdrawiam</cpp>

0

zakladam ze struktura pliku XML jest Ci znana, jest sztywna i ze zakladasz ze plik XML jest poprawny.

  1. w plikach XML znaki < oraz > maja prawo wystepowac tylko i wylacznie jako ograniczniki tagaow, w wartosciach atrybutow oraz sekcjacj CDATA (porpawcie mnie jesli nie) musza zostac zamienione na encje < oraz >, odpowiednio. To znaczy, ze mozesz w bardzo prosty sposob wykrywac poczatki i konce tagow: po prostu sprawdzaj czy na danej pozycji jest <litera albo <\litera

  2. maja prawo istniec tagi krotkie, nie zakanczane <\tag> -- sa to <tag />, trzeba to miec w pamieci i kazdy zauwazony nowy tag sprawdzac czy nie konczy sie on />

  3. poprawnie skonstruowany XML ma zbalansowane tagi: kazdy tag otwarty ma zamkniecie, z uwaga na punkt 2. To znaczy, ze mozesz latwo orientowac sie co jest zawartoscia danego taga poprzez albo pracę stosową z pamietaniem gdzie-teraz-jestem, albo prace z look-ahead'em i zliczaniem wystapien samego siebie.

omawianie stosu sobie daruje, bo jest tego pelno. Natomiast, jesli Twoj XML jest prosty i nierozbudowany, mozesz sprobowac podgladactwa-w-przód. Majac XML:
...

.< - tu aktualnie 'jestes' z ogladaniem pliku
<BLAH>
<BUM>
<BLAH>
<BLAH />
</BLAH>
</BLAH>
...
mozesz w prosty sposob dowiedziec sie, gdzie Twoj obecnie widziany tag 'BLAH' sie konczy: przegladasz znaki w przod (lookahead) i obserwujesz czy pojawia sie takie (regexp..):
<BLAH
<BLAH[^/>]*/>
</BLAH\s+>
jezeli pojawi sie pierwszy, to znaczy ze w Twoim tagu jest inny taki. Zapamietaj ile bylo takich.
jezeli pojawi sie drugi -- olej. to jest krotki tag, on niczego nie wnosi do probelmu startu-konca
jezeli pojawi sie trzeci - o, cos zostalo zamkniete. albo Twoj tag, albo jeden z wewnetrznych. Jezeli liczba zamkniec = liczba widzianych wewnetrznych+1 ----- to znaczy, ze To Twoje zamkniecie, voil'a -- znalazlem koniec!

  1. umiejac znalezc swoj poczatek i koniec swojego taga, mozesz teraz obejrzec jego wnetrze. Analogicznie, tylko z innym tagiem, nie BLAH tylko inny. Jak bedziesz mial kod ogladajacy w ten sposob wszystko, az do "dna" - to na dnie okaze sie ze bedziesz mial kod, ktory oglada wnetrza tekstowe -- wystarczy je skopiowac do swoich struktur w pamieci --- albo ktory oglada atrybuty tagow -- wystarczy je skopiowac..

natomiast, jezeli potrafisz poslugiwac sie stosem, zacznij od tego rekurencyjnie:
idz w przod, ogladaj znaki. <litera oznacza nowy tag, wez jego nazwe, jezeli ten tag nie konczy sie znakami /> to wrzuc nazwe na stos. <\litera oznacza zamkniecie taga, zdejmij tego taga ze stosu. jesli nazwa sie nie zgadza z nazwa na stosie - blad, plik lub Twoj kod jest walniety.
takie cos jest w stanie przejsc po calym XMLu trafiajac we wszystko lub przeskakujac text luzno latajacy. W taka ramowke wcisniesz sprawdzanie czy znaleziony tagname==BLAH albo czy "teraz leci luzny tekst" i na podstawie nazwy taga lezacej na czubku stosu, bedziesz wiedzial czy cos robic ze znaleziona zawartoscia, czy tez nic i leciec dalej

wzgledem bibliotek xerces, expat, czy msxml czy innych -- reczne podejscie ma ten minus, ze nie bedziesz mial walidacji xsd, obslugi namespacow, obslugi(....) - chyba ze sam napiszesz..

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