PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : XML Strings auseinandernehmen


silo
20.04.2007, 08:48
Hallo,
ich bin gerade auf der Suche nach einer Möglichkeit wie ich in einem String gespeicherte XML Daten auseinandernehmen kann.
Dabei bin ich auf ein fieses Problem gestossen.
Ich arbeite mit Java und reguläre Ausdrücke sind relativ neu für mich.


Hier ist ein Beispiel für die zugrunde liegeneden XML-Daten

... <abschnitt attribut="Ich <b>grüße</b> Sie"> ... </abschnitt> ...


Aufgrund der Tatsache das [<&"] nicht in einem XML-Attribut vorkommen dürfen (somit obiger String keine valides XML ist), sieht das ganze vor dem Parsen etwa so aus:

... <abschnitt attribut="Ich &lt;b>grüße&lt;/b> Sie"> ... </abschnitt> ...


Das was ich im Programm hinterher benötige ist in diesem Beispiel die komplette Markup auszeichnung, also das was rot gekennzeichnet ist.

Mein erster Ansatz war folgender:

(<.*?>)


Da hier allerdings (was ich auch erwartet hatte) der Inhalt des Attributs mitgeparst wird bekam ich ein Ergebniss das so aussah:
<abschnitt attribut="Ich &lt;b>

Aber auch nach einer Modifikation des Ausdruckes in
(<.*?(?:".*?")*.*?>)
half mir nicht, da das selbe Ergebniss ausgegeben wurde.
Und an dieser Stelle weiss ich auch nicht mehr warum das so ist.

Was ich letztenendes benötige ist eine Möglichkeit wie ich einem regulärem Ausdruck mitteilen kann, das er Treffer die in einer bestimmten Auszeichnung stehen (sei es nun "x y z", 'x y z', #x y z# oder was auch immer) ignoriert werden sollen.

Über eine Antwort würde ich mich sehr freuen.
Mfg


btw.: Ich habe die Java Optionen

Pattern.CASE_INSENSITIVE
Pattern.MULTILINE
Pattern.DOTALL


Tweedledee
20.04.2007, 13:53
Benutze org.xml.sax

http://java.sun.com/j2ee/sdk_1.3/techdocs/api/org/xml/sax/package-frame.html

silo
24.04.2007, 11:58
Hallo Tweedledee,

vielen Dank für deine Antwort.
Wenn ich XML verarbeiten möchte werde ich selbstverständlich eine Lösung wie SAX oder DOM wählen, doch mir ging es eher um die Verarbeitung von Strings (wie im letzten Satz beschrieben).

Das ist wohl nicht so ganz rübergekommen, deshalb versuche ich es mal an einem anderen Beispiel zu erklären.

Angenommen in einer *.java Datei steht unter anderem folgender Inhalt:

String einfacherSazt = "Mit dem \\-Zeichen kann man innerhalb eines durch \"-Zeichen eingeschlossenen Strings ein \"-Zeichen ausgeben, indem man das \"-Zeichen folgendermaßen auskommentiert: \\\" ";
Ich lese die Datei ein, und nun möchte ich einen regulären Ausdruck der mir das oben rot-Markierte in einer Variablen speichert.
Und nicht einfach nur das im folgendem Codeblock rot Markierte.

String einfacherSazt = "Mit dem \\-Zeichen kann man innerhalb eines durch \"-Zeichen eingeschlossenen Strings ein \"-Zeichen ausgeben, indem man das \"-Zeichen folgendermaßen auskommentiert: \\\" ";
Hier verhält es sich ganz ähnlich wie in den Beispiel aus dem ersten Beitrag. Es ist die gleiche Problemstellung.
Ich suche alle Zeichen zwischen zwei Begrenzungszeichen (bei XML sind das < und >, bei Java sind es " und "). Allerdings soll das jeweils schliessende Zeichen nicht berücksichtigt werden wenn es in einer ganz bestimmten Form ausgezeichnet wurde (bei XML duch " und ", bei Java durch ein vorangestelltes \).


Und um nochmal zum XML-Beispiel zurückzukommen, verstehe ich eben nicht warum der zweite reguläre Ausdruck nicht funktioniert.

Ich hoffe meine Absicht sind durch die Erläuterung verständlicher geworden.
Über eine Antwort würde ich mich sehr freuen.


Mfg

Tweedledee
25.04.2007, 10:23
Da hatte ich dich wohl mißverstanden, vielleicht tue ich es immer noch. Denn in dem oberen Beispiel

... <abschnitt attribut="Ich &lt;b>grüße&lt;/b> Sie"> ... </abschnitt> ...
ist ja nur das < durch &lt; codiert, nicht aber das > durch &gt;. Wenn das der Fall ist funktionieren ja beide Suchmuster.

Zu dem unteren Beispiel:


String einfacherSazt = "Mit dem \\-Zeichen kann man innerhalb eines durch \"-Zeichen eingeschlossenen Strings ein \"-Zeichen ausgeben, indem man das \"-Zeichen folgendermaßen auskommentiert: \\\" ";
Das funktioniert bei mir mit

("(?:[^"]|(?:\"))*)"bzw. nochmal für Java kodiert:

findMatches("(\"(?:[^\"]|(?:\\\"))*)\"" , einfacherSatz)Gruß Tweedledee

silo
25.04.2007, 17:41
Hallo Tweedledee,

vielen Dank, das mit den Anführungszeichen in Java funktioniert.

Aber das mit den XML-String klappt nicht.
Das Problem bei der Sache ist, das ich es im Sinne der XML-Spezifikation nicht verhindern kann das ein User in ein Attribut das >-Zeichen eintippt. Es wäre zwar schön wenn er auch dieses durch &gt; codiert, aber die wenigsten machen das.

Letztenendes habe ich die Schwiegigkeit, das der Treffer bei ersten >-Zeichen zuende ist.
Im meinen Augen liegt mein Denkfehler an folgendem Sachverhalt.

Bei diesem Muster

(<.*?(?:".*?")*.*?>)]
^ ^

findet die innere Klammer (durch Pfeile markiert) beliebig viele, durch Anführungszeichen eingeschlossese Zeichen, und das beliebig oft (durch den Stern).

Bei folgendem String (rotmarkiert ist das Ergebniss bei obigem Muster)
... <abschnitt attribut=">" attribut2=">" attribut3=">"> ...
würde ich mich freuen wenn der Stern für die drei Attribute steht, jedoch scheint es so als wird er als "kein mal" interpretiert, und das >-Zeichen im ersten Attribut markiert das Ende des treffers (was ich auch irgentwie nachvollziehen kann, denn das macht ja irgentwo auch durchaus Sinn).


Ersetze ich beispielsweise im Muster den Stern durch ein Plus, dann kommt folgendes heraus (rotmarkiert ist das Ergebnis):

Muster: (<.*?(?:".*?")+.*?>)]

Code: ... <abschnitt attribut=">" attribut2=">" attribut3=">"> ...

Hier wird das Plus auch "nur" als das mindestmaß (also einmal) gesehen, und nicht als drei mal (wie ich es mir wünschen würde).


Um noch mal klarzustellen: Was ich suche, ist ein Treffer der den ganzen Start-Tag mit allen Attributen zurückgibt (also das rot markeirte in folgendem Abschnitt):
... <abschnitt attribut=">" attribut2=">" attribut3=">"> ...


Mfg

Jan Krüger
25.04.2007, 18:28
Ein ">" in einem Attributstring ist meines Wissens ungültig. Wenn du also auf sowas stößt, bist du im Prinzip durch den XML-Standard dazu verpflichtet, die Eingabe zu verwerfen.

silo
26.04.2007, 08:01
Ein ">" in einem Attributstring ist meines Wissens ungültig. Wenn du also auf sowas stößt, bist du im Prinzip durch den XML-Standard dazu verpflichtet, die Eingabe zu verwerfen.

Leider nicht :(
http://www.w3.org/TR/REC-xml/ (http://www.w3.org/TR/REC-xml/#NT-AttValue)

Jan Krüger
26.04.2007, 19:24
Hm, dann schlage ich vor:

(<[^>]*?(?:"[^"]*?")*[^>]*?>)

Ist jetzt aber mal spontan ungetestet. :)

silo
01.05.2007, 15:07
Hallo,
das klappt leider auch nicht.
Da kommt das rot markierte heraus.

Muster: (<[^>]*?(?:"[^"]*?")*[^>]*?>)

Code: ... <abschnitt attribut=">" attribut2=">" attribut3=">"> ...

kill4h`
01.05.2007, 15:40
Hast du denn Zugriff auf die Eingaben vom User? Dann könnte man ja Steuerzeichen codieren...

Zum Ausdruck: Kann man in Java auch Lookaround-Zusicherungen entwerfen? Oder ist das nur in Perl kompatiblen Dialekten möglich?

Jan Krüger
01.05.2007, 21:25
Ja, sorry, schlecht gedacht.

Wie ist's hiermit:
(<([^">]*?(?:"[^"]*?")*)+>)
Zumindest in Ruby klappt das ganz gut.

Assertions sind, soweit ich weiß, in Java nicht drin.

silo
03.05.2007, 07:50
Super, das klappt.
Und jetzt verstehe ich auch endlich warum mein ursprünglicher Ausdrück nicht funktioniert.

Danke für die Hilfe.
:)