Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

xmlstarlet

20 views
Skip to first unread message

Jan Schmidt

unread,
May 30, 2013, 2:53:39 PM5/30/13
to
Hallo Leute,

ich muss eine xml-Datei transformieren. Dazu habe ich bisher
das kurze Shell-Script verwendet.

xml sel -T -t -m '//*/text' -v '@lang' -n $IN |sort|uniq |while read i; do
xml tr ${PFAD}/xml2text.xslt -s sprache="$i" $IN >${OUT}_${i}.txt
done

Leider ist das unter Win (MSYS) extrem langsam (100 fache
Ausfᅵhrungsdauer gegenᅵber Linux). Ich habe herausgefunden, dass das
an der Pipe-Verbindung vor dem while liegt.

Jetzt die Frage: Kann man das Konstrukt irgendwie direkt in xml
abbilden, so dass xmlstarlet sort und uniq mit erledigt?

Ich bin schon beim sort gescheitert.

Die xml-Datei sieht ungefᅵhr so aus.

<test>
<a>
<text lang="de"/>
</a>
<b>
<text lang="en"/>
</b>
<c>
<text lang="de"/>
</c>
</test>

Der erste Aufruf erzeugt mehrere tausend Zeilen, nach dem uniq kommen
vielleicht 5 raus.

Zur Not kᅵnnte das auch in das Stylesheet mit rein, aber da habe
ich auch keinen Plan wie das anzustellen ist. Das scheitert ja
schon daran, dass mehrere Ausgabedateien zu erzeugen sind.

Vielen Dank
jan

Holger Marzen

unread,
May 30, 2013, 2:56:37 PM5/30/13
to
["Followup-To:" nach de.comp.os.unix.apps.misc gesetzt.]
* On Thu, 30 May 2013 20:53:39 +0200, Jan Schmidt wrote:

> Hallo Leute,
>
> ich muss eine xml-Datei transformieren. Dazu habe ich bisher
> das kurze Shell-Script verwendet.
>
> xml sel -T -t -m '//*/text' -v '@lang' -n $IN |sort|uniq |while read i; do
> xml tr ${PFAD}/xml2text.xslt -s sprache="$i" $IN >${OUT}_${i}.txt
> done
>
> Leider ist das unter Win (MSYS) extrem langsam (100 fache
> Ausführungsdauer gegenüber Linux). Ich habe herausgefunden, dass das
> an der Pipe-Verbindung vor dem while liegt.

Geht es schneller, wenn Du in jedem Schritt eine Datei erzeugst und
diese im nächsten Schritt einliest?

Helmut Hullen

unread,
May 30, 2013, 4:12:00 PM5/30/13
to
Hallo, Jan,

Du meintest am 30.05.13:

> ich muss eine xml-Datei transformieren. Dazu habe ich bisher
> das kurze Shell-Script verwendet.

> xml sel -T -t -m '//*/text' -v '@lang' -n $IN |sort|uniq |while read
> i; do xml tr ${PFAD}/xml2text.xslt -s sprache="$i" $IN
> >${OUT}_${i}.txt done

[...]

> Ich bin schon beim sort gescheitert.

Klitzekleines Detail (wird die Geschwindigkeit nicht sonderlich
beeinflussen):

anstelle von "sort | uniq " sollte "sort -u" reichen.

Viele Gruesse
Helmut

"Ubuntu" - an African word, meaning "Slackware is too hard for me".

Stefan Reuther

unread,
May 31, 2013, 12:35:11 PM5/31/13
to
Jan Schmidt wrote:
> ich muss eine xml-Datei transformieren. Dazu habe ich bisher
> das kurze Shell-Script verwendet.
>
> xml sel -T -t -m '//*/text' -v '@lang' -n $IN |sort|uniq |while read i; do
> xml tr ${PFAD}/xml2text.xslt -s sprache="$i" $IN >${OUT}_${i}.txt
> done
>
> Leider ist das unter Win (MSYS) extrem langsam (100 fache
> Ausführungsdauer gegenüber Linux). Ich habe herausgefunden, dass das
> an der Pipe-Verbindung vor dem while liegt.

Sobald die Pipe einmal steht, sollte das eigentlich recht flott gehen.

Was ist denn 'xml' für ein Tool? Ich habe meine XML-Spielereien mit
'LotusXSL' angefangen, einem (damals) grottenlahmen Java-Teil, bis ich
'xsltproc' gefunden habe, was Kreise um LotusXSL rennt.

> Jetzt die Frage: Kann man das Konstrukt irgendwie direkt in xml
> abbilden, so dass xmlstarlet sort und uniq mit erledigt?
>
> Ich bin schon beim sort gescheitert.

Genau daran bin ich in XSLT auch gescheitert, bzw. die produzierten
Lösungen hatten irgendwas von O(n^4).

Du kannst aber mit dem Shellscript ein Stylesheet erzeugen, das ein
Template des existierenden Stylesheets aufruft, so dass du am Ende nur
einen 'xml tr'-Aufruf in der Pipeline hast.

> Zur Not könnte das auch in das Stylesheet mit rein, aber da habe
> ich auch keinen Plan wie das anzustellen ist. Das scheitert ja
> schon daran, dass mehrere Ausgabedateien zu erzeugen sind.

Du könntest ein großes Ausgabedokument erstellen, Beißmarken einfügen
und es nachher anhand dieser in mehrere Dokumente aufteilen.


Stefan

Jan Schmidt

unread,
May 31, 2013, 4:15:37 PM5/31/13
to
Stefan Reuther schrieb:
> Jan Schmidt wrote:
>> ich muss eine xml-Datei transformieren. Dazu habe ich bisher
>> das kurze Shell-Script verwendet.
>>
>> xml sel -T -t -m '//*/text' -v '@lang' -n $IN |sort|uniq |while read i; do
>> xml tr ${PFAD}/xml2text.xslt -s sprache="$i" $IN >${OUT}_${i}.txt
>> done
>>
>> Leider ist das unter Win (MSYS) extrem langsam (100 fache
>> Ausführungsdauer gegenüber Linux). Ich habe herausgefunden, dass das
>> an der Pipe-Verbindung vor dem while liegt.
>
> Sobald die Pipe einmal steht, sollte das eigentlich recht flott gehen.
>
> Was ist denn 'xml' für ein Tool?

http://xmlstar.sourceforge.net/

ich nehme das recht gern. Ist selbst als static nicht groß, hat
keine Abhängigkeiten und kann ziemlich viel. Ist auch schneller
als die ganzen java-basierten Tools.

Ich habe jetzt mal festgelegt, dass alle tags auf einer neuen
Zeile beginnen müssen und das ganze mit awk gemacht. Das hat
Beschleunigung von 25s auf <2s gebracht. Das reicht erstmal.

>> Ich bin schon beim sort gescheitert.
>
> Genau daran bin ich in XSLT auch gescheitert, bzw. die produzierten
> Lösungen hatten irgendwas von O(n^4).

An sich funktioniert das ganz gut. Problem hier in dem Fall ist,
dass die zu sortierenden Elemente verschiedene Eltern-Tags haben - und
auch noch in verschiedenen Ebenen stehen. Dann sortiert xslt jede
Ebene separat. Das habe ich dem nicht abgewöhnen können.

jan

Tim Landscheidt

unread,
May 31, 2013, 6:17:42 PM5/31/13
to
Jan Schmidt <jan.s...@gmx.de> wrote:

> [...]

>>> Ich bin schon beim sort gescheitert.

>> Genau daran bin ich in XSLT auch gescheitert, bzw. die produzierten
>> Lösungen hatten irgendwas von O(n^4).

> An sich funktioniert das ganz gut. Problem hier in dem Fall ist,
> dass die zu sortierenden Elemente verschiedene Eltern-Tags haben - und
> auch noch in verschiedenen Ebenen stehen. Dann sortiert xslt jede
> Ebene separat. Das habe ich dem nicht abgewöhnen können.

Per Stylesheet ist das nicht so kompliziert:

| <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

| <xsl:key name="languages" match="//text" use="@lang"/>

| <xsl:template match="/test">
| <xsl:for-each select="//text[generate-id() = generate-id(key('languages', @lang))]/@lang">
| <xsl:sort select="."/>
|
| <xsl:value-of select="concat(., '&#10;')"/>
| </xsl:for-each>
| </xsl:template>
| </xsl:stylesheet>

(Nein, ich muss das auch immer nachschlagen.) Ob man das
auch in einen XPath pressen kann, weiß ich nicht.

Tim
0 new messages