Frage

Stellen Sie sich vor ich habe die Folling XML-Datei:

vor Mitte nach

Ich mag es konvertieren in etwa so aus:

beforemiddleafter

Mit anderen Worten möchte ich alle untergeordneten Knoten eines bestimmten Knoten zu bekommen, und sie an den übergeordneten Knoten, um zu bewegen. Das ist wie Sie diesen Befehl ausführen: "mv ./directory/*"., Aber für XML-Knoten

Ich mag die Unix-in mit Kommandozeilen-Tool tun. Ich habe mit xmlstarlet versucht, die eine leistungsfähige XML-Manipulator-Befehlszeile ist. Ich habe versucht, so etwas wie dies zu tun, aber es funktioniert nicht

echo " vor Mitte nach " | xmlstarlet ed -m "// b / *" ".."

Update: XSLT-Templates sind in Ordnung, können, da sie von der Kommandozeile aufgerufen werden

.

Mein Ziel hier ist ‚die Links von einer XHTML-Seite entfernen‘, mit anderen Worten ersetzen, wo der Link war, mit dem Inhalt der Link-Tags.

War es hilfreich?

Lösung

Wenn Ihr eigentliches Ziel ist es, die Links von einer Webseite zu entfernen, dann sollten Sie ein Stylesheet wie folgt verwenden, die alle Elemente <a> XHTML Spiele (ich nehme an, Sie XHTML verwenden?) Und einfach gilt Vorlagen für ihre Inhalt:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:h="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="h">

<!-- Don't copy the <a> elements, just process their content -->
<xsl:template match="h:a">
  <xsl:apply-templates />
</xsl:template>

<!-- identity template; copies everything by default -->
<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Dieses Sheet mit einer Situation umgehen wird, wo man etwas verschachtelt haben in das <a> Element, das Sie behalten möchten, wie zum Beispiel:

<p>Here is <a href="....">some <em>linked</em> text</a>.</p>

, die Sie wollen kommen wie:

<p>Here is some <em>linked</em> text.</p>

Und es wird mit der Situation umgehen, wenn Sie den Link in einem unerwarteten Elemente zwischen dem üblichen Elternteil (das <p> Element) und dem <a> Elemente, wie verschachtelt haben:

<p>Here is <em>some <a href="...">linked</a> text</em>.</p>

Andere Tipps

Beispiel-Eingabedatei (test.xml):

<?xml version="1.0" encoding="UTF-8"?>
<test>
<x>before<y>middle</y>after</x>
<a>before<b>middle</b>after</a>
<a>before<b>middle</b>after</a>
<x>before<y>middle</y>after</x>
<a>before<b>middle</b>after</a>
<embedded>foo<a>before<b>middle</b>after</a>bar</embedded>
</test>

Stylesheet (collapse.xsl:

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

      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>

      <xsl:template match="a">
        <xsl:copy>
          <xsl:value-of select="."/>
        </xsl:copy>
      </xsl:template>

    </xsl:stylesheet>

Ausführen mit xmlstarlet mit

xml tr collapse.xsl test.xml

Erzeugt:

<?xml version="1.0"?>
<test>
<x>before<y>middle</y>after</x>
<a>beforemiddleafter</a>
<a>beforemiddleafter</a>
<x>before<y>middle</y>after</x>
<a>beforemiddleafter</a>
<embedded>foo<a>beforemiddleafter</a>bar</embedded>
</test>

Die erste Vorlage im Stylesheet ist die grundlegende Identität Transformation (nur kopiert die ganze Ihr Eingabe-XML-Dokument). Die zweite Vorlage passt speziell auf die Elemente, die Sie ‚Zusammenbruch‘ wollen und nur Kopien der Tags und fügt den String-Wert des Elements (= Verkettung der Zeichenfolge-Wert von absteigenden Knoten).

In XSLT, könnten Sie einfach schreiben:

<xsl:template match="a"><a><xsl:apply-templates /></a></xsl:template>

<xsl:template match="a/b"><xsl:value-of select="."/></xsl:template>

Und du würdest erhalten:

<a>beforemiddleafter</a>

Wenn Sie also diesen den einfachen Weg machen wollen Sie nur einen XSL-Stylesheet erstellen könnten und Ihre XML-Datei durch, die ausgeführt werden.

Ich weiß, das ist nicht das, was Sie sagen, Sie tun möchten (mit Unix-Kommandozeile), jedoch. Ich weiß nichts über Unix, so vielleicht jemand anderes in die Lücken füllen, zB. eine Art Befehlszeile fordert, dass die oben ausführen kann.

Mit xmlstarlet:

xmlstr='<a>before<b>middle</b>after</a>'
updatestr="$(echo "$xmlstr" | xmlstarlet sel -T -t -m "/a/b" -v '../.' -n | sed -n '1{p;q;}')"
echo "$xmlstr" | xmlstarlet ed -u "/a" -v "$updatestr"

Haben Sie versucht das?

file.xml

<r>
    <a>start<b>middle</b>end</a>
</r>

template.xsl

<xsl:template match="/">
    <a><xsl:value-of select="r/a" /></a>
</xsl:template>

output

<a>startmiddleend</a>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top