Marvin Esse: Über Linux shell script XML auslesen

Guten Morgen Leute,

ich habe ein eher Linux-technisches Problem und bin mir sicher, dass hier jemand dabei ist, der mir weiterhelfen kann.

Ich habe eine (ziemlich umfangreiche) XML-Datei, mit der folgenden (übersichtlichen) Struktur:

<baum>
  <feld pfad="/test/123/x y z/abc">
    <name>Michael</name>
    <rechte>RW</rechte>
  </feld>
  <feld pfad="/test/123/x y z">
    <name>Marvin</name>
    <rechte>RW</rechte>
  </feld>
</baum>

Ich hab ein Script gefunden/gebaut, mit dem ich schon bei Eingabe eines Begriffs, die gefundenen Felder anzeigen lassen kann:

y="$1"
up="$(echo $y | tr 'A-Z' 'a-z')"
lo="$(echo $y | tr 'a-z' 'A-Z')"
echo "cat //baum/*[contains(translate(.,'$up','$lo'),'$lo')]" | xmllint --shell /media/data/database.xml

Bei Eingabe von bspw. "Marvin" wird mir zurückgegeben:

  <feld pfad="/test/123/x y z">
    <name>Marvin</name>
    <rechte>RW</rechte>
  </feld>

Aber wie kann ich nach "/test/123/x y z" suchen und ebenso die feld-Struktur(en) als Ergebnis anzeigen lassen? Ich schaffe es leider bisher nicht nach Sonderzeichen oder auch nach Leerzeichen suchen lassen.

Liege Grüße,

Marvin

  1. ich habe ein eher Linux-technisches Problem

    Ich habe eine (ziemlich umfangreiche) XML-Datei

    Du hast ein XML-Problem.

    <baum>
      <feld pfad="/test/123/x y z/abc">
        <name>Michael</name>
        <rechte>RW</rechte>
      </feld>
    

    wie kann ich nach "/test/123/x y z" suchen

    Du möchtest nach einem Element suchen, dessen Attribut pfad den Wert "/test/123/x y z" hat. Der XPath-Ausdruck dafür wäre *[@pfad='/test/123/x y z'] (kurz) oder *[attribute::pfad='/test/123/x y z'] (lang); vermutlich möchtest du noch // oder //baum/ davorsetzen. Siehe https://www.w3.org/TR/xpath/#location-paths

    1. Ich möchte nicht nur nach dem extakten und vollständigen Pfad suchen können, sondern auch nach Teilen. Also alles wo "x Y Z" vorkommt oder auch alles was mit "/test" anfängt. Wie ich eingangs geschrieben hatte, verwende ich momentan dafür

      cat //baum/*[contains(translate(.,'$up','$lo'),'$lo')]" | xmllint --shell /media/data/database.xml
      

      Einmal um unabhängig von Groß- und Kleinschreibung zu sein und um auch nach Begriffen innerhalb suchen zu können. Was mir fehlt ist die Möglichkeit auch nach Suchbegriffen suchen zu können, die Leerzeichen oder Sonderzeichen enthalten können.

      Funktioniert hierfür das "contains" nicht? Ich habe es mit Maskieren über "" probiert und auch ohne, erziele aber damit leider dann gar keine Ergebnisse, es wird dann nichts gefunden.

      LG Marvin

      1. Hallo,

        Was mir fehlt ist die Möglichkeit auch nach Suchbegriffen suchen zu können, die Leerzeichen oder Sonderzeichen enthalten können.

        das übliche Escape-Zeichen in der Shell ist der Backslash; alternativ kannst du den ganzen Ausdruck, in dem die Leerzeichen vorkommen, in Anführungszeichen setzen.

        Funktioniert hierfür das "contains" nicht?

        Doch, vermutlich schon (ich habe keine Ahnung von den XML-Tools, die du verwendest, daher nur "vermutlich"). Aber ein unmaskiertes Leerzeichen trennt Kommandozeilen-Argumente voneinander. Andere Shell-Sonderzeichen, die maskiert werden müssen, sind z.B. eckige und geschweifte Klammern, AFAIK auch der Stern und sicher noch ein paar andere.

        Ich habe es mit Maskieren über "" probiert

        Wie genau?

        So long,
         Martin

        --
        Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
        - Douglas Adams, The Hitchhiker's Guide To The Galaxy
        1. das übliche Escape-Zeichen in der Shell ist der Backslash; alternativ kannst du den ganzen Ausdruck, in dem die Leerzeichen vorkommen, in Anführungszeichen setzen.

          Ich habe den üblichen Backslash als erstes versucht und auch schon den Suchbegriff komplett in Anführungszeichen.

          Also sowohl "x y z" als auch "x\ y\ z". Oder auch "\/test\/123" usw. (Hier im Forum muss ich also auch escapen, damit es korrekt angezeigt wird ^^ )

          xmlint dürfte eigentlich bei jeder Linux-Distribution standard sein. Ich verwende ein SUSE SLES.

          LG Marvin

          1. Hi,

            das übliche Escape-Zeichen in der Shell ist der Backslash; alternativ kannst du den ganzen Ausdruck, in dem die Leerzeichen vorkommen, in Anführungszeichen setzen.

            Ich habe den üblichen Backslash als erstes versucht und auch schon den Suchbegriff komplett in Anführungszeichen.

            beim Aufruf des Scripts an der Kommandozeile? - Da sollten eigentlich beide Varianten das Gewünschte leisten. Lass dir doch im Script mal den Inhalt von $y zur Kontrolle ausgeben, dann siehst du, ob das Argument wenigstens korrekt mit allen Zeichen erkannt wurde.

            Also sowohl "x y z" als auch "x\ y\ z". Oder auch "\/test\/123" usw.

            Genau so sollte es eigentlich gehen. Es sei denn, xmllint verlangt seinerseits noch bestimmte Escaping-Regeln. Da muss ich dann aber passen (keine Ahnung).

            (Hier im Forum muss ich also auch escapen, damit es korrekt angezeigt wird ^^ )

            Korrekt.

            xmlint dürfte eigentlich bei jeder Linux-Distribution standard sein.

            Das mag schon sein, trägt aber nicht zur Lösung bei. ;-)

            So long,
             Martin

            --
            Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
            - Douglas Adams, The Hitchhiker's Guide To The Galaxy
            1. Für alle die es interessieren sollte:

              echo "cat //baum/feld[contains(translate(@*,'$up','$lo'),'$lo')]" | xmllint --shell /media/nss/data/database.xml
              

              Ich musste jetzt auch nicht einmal die Sonderzeichen maskieren.

              LG

              Marvin