Laden...

Per Regex XML Tag mit speziellem unter-TAG finden

Erstellt von christof.k vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.371 Views
C
christof.k Themenstarter:in
159 Beiträge seit 2005
vor 13 Jahren
Per Regex XML Tag mit speziellem unter-TAG finden

Hallo,

ich weiß, das Thema ist schon tausend mal durchgesprochen, aber leider nur "fast". Ich habe nun zwei Tage lang Google und eine Stunde das Forum durchsucht und bin auch "fast" fündig geworden.

Mein Problem:


<SW-INSTANCE>
	456
</SW-INSTANCE>
<SW-INSTANCE>
	123
	a456a
</SW-INSTANCE>
<SW-INSTANCE>
	a89a
</SW-INSTANCE>

Dort möchte ich nur den Tag, in dem z.B. der Text 123 vorkommt, finden.
Ich muss auf Regex zugreifen, da ich mir ein Command-Line Regex tool geschrieben habe, welches gut funktioniert. Deshalb möchte ich nicht auf andere Klassen zurückgreifen.

Einen Tag selbst kann man ja per

<SW-INSTANCE>.*?</SW-INSTANCE>

erhalten.
Wenn ich diesen nun aber auf

<SW-INSTANCE>.*?123.*?</SW-INSTANCE>

erweitere, fängt das Match beim ersten <SW-INSTANCE> an, und nicht beim entsprechenden.
Irgendwie sehe ich leider den Wald vor lauter Bäumen nicht und hoffe auf Eure hilfe.

Vielen Dank!

Christof

2.891 Beiträge seit 2004
vor 13 Jahren

Du musst deinen regulären Ausdruck so anpassen, dass er nur so matched, dass es zwischen dem öffnenden Tag und dem schließenden keinen anderen Tag gibt. Benutze dazu nicht ".", sondern "[<]". (Oder "[>]".)

Guck dir auch mal RegEx kürzester Match [und die Gefahren von .*?] an.

Gruß,
dN!3L

C
christof.k Themenstarter:in
159 Beiträge seit 2005
vor 13 Jahren

Mein vorheriges Beispiel hatte ich vereinfacht, aber anscheinend zu sehr, sorry.

Der eigentliche Fall ist "etwas" komplexer:

<SW-INSTANCE><SW-CS-STATE>changed</SW-CS-STATE>
<REMARK/>
</SW-INSTANCE>
<SW-INSTANCE><SW-CS-STATE>changed</SW-CS-STATE>
<REMARK>text123</REMARK>>
<DATE>2009-02-17T11:25:06</DATE></SW-INSTANCE>

Wenn ich nun alle "SW-INSTANCE" Tags löschen möchte, die das untertag REMARK leer haben (also <REMARK/>) funzt das nun nicht mehr, da es auf einmal ganz viele '>' Zeichen gibt.

Zufällig dafür noch einen Tip?
Danke!
Christof

2.891 Beiträge seit 2004
vor 13 Jahren

Der eigentliche Fall ist "etwas" komplexer

Reguläre Ausdrücke sind nicht geeignet, um (komplexes) XML zu verarbeiten (Coding Horror: Parsing Html The Cthulhu Way).
Nimm besser XPath: doc.SelectNodes("//SW-INSTANCE/REMARK[contains(.,'123')]")

Gruß,
dN!3L

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo christof.k,

obwohl ich Regex-Fan bin, würde auch ich eher zu XPath raten.

Wenn du unbedingt Regex nehmen willst, kannst du über negative look-ahreads sicherstellen, dass in dem Match keine unerwünschten Tags enthalten sind. Ich habe ein entsprechendes PS in RegEx kürzester Match [und die Gefahren von .*?] hinzugefügt.

herbivore

C
christof.k Themenstarter:in
159 Beiträge seit 2005
vor 13 Jahren

Hi,

nach all den Argumenten habe ich XPath versucht und bin begeistert.
Was ich nun machen werde ist, per XPath den Node zu finden und den Inhalt per Regex auf meine Bedingungen zu prüfen (und dann potentiell zu ändern).
Erste Versuche sehen gut aus.

Danke nochmals!
Christof