2015-02-12 13 views
5

Ich versuche, eine große Anzahl von XML-Dateien (Maven Poms) mit xmllint --xpath zu verarbeiten. Mit etwas Versuch und Irrtum habe ich herausgefunden, dass es nicht als aufgrund der schlechten Standard-Namespace-Deklaration in diesen Dateien erwartet funktioniert, die wie folgt lautet:Force xmllint zu ignorieren schlecht defult xmlns

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 

Ein einfacher Befehl schlägt fehl, wie folgt:

$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml) 
XPath set is empty 

Wenn ich den xmlns loswerden Attribut, folgt das Wurzelelement ersetzt wie:

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 

der vorherige Befehl gibt die erwartete Ausgabe:

$ echo $(xmllint --xpath '/project/modelVersion/text()' pom.xml) 
4.0.0 

Das Ändern von Hunderten von Pom-Dateien ist keine Option, zumal sich Maven selbst nicht beschwert.

Gibt es eine Möglichkeit für die xmllint, die Datei mit dem schlechten xmlns zu verarbeiten?

UPDATE

Dank Damien konnte ich einige Fortschritte machen:

$ (echo setns x=http://maven.apache.org/POM/4.0.0; echo 'xpath /x:project/x:modelVersion/text()';) | xmllint --shell pom.xml 
/> setns x=http://maven.apache.org/POM/4.0.0 
/> xpath /x:project/x:modelVersion/text() 
Object is a Node Set : 
Set contains 1 nodes: 
1 TEXT 
    content=4.0.0 

Aber das tun nicht ganz das, was ich brauche. Meine Follow-up-Fragen lauten wie folgt:

  1. Gibt es eine Möglichkeit, nur den Text zu drucken? Ich möchte, dass die Ausgabe 4.0.0 im obigen Beispiel enthält

  2. Es scheint, dass die Ausgabe nach etwa 30 Zeichen abgeschnitten wird. Ist es möglich, eine vollständige Ausgabe zu erhalten? Dies geschieht nicht mit xmllint --xpath

+0

Es ist kein * schlechter * Namespace. Es ist ein Namensraum.Das bedeutet normalerweise, dass Sie auch den Namespace in Ihrer XPath-Abfrage verwenden müssen, aber ich bin nicht mit den Details des Tools vertraut, das Sie verwenden, um Ihnen genau zu sagen, wie genau. –

+0

Es ist schlecht, weil es xmllint fehlschlägt :) Auch weil die schlevelocation falsch ist. –

+1

Ein bisschen einfache Suche auf 'xmllint Namespace' aufgetaucht [diese Frage] (http://stackoverflow.com/questions/8264134/xmllint-failing-to-properly-query-with-xpath), die zwei mögliche zu zeigen scheint Arbeitsweisen * mit * dem Namespace. Und das Schema scheint korrekt zu sein. Es besagt, dass das Schema, das durch die URI "http: // maven.apache.org/POM/4.0.0" identifiziert wurde, unter der URL "http: // maven.apache.org/maven-v4_0_0.xsd" und "http: // maven.apache.org/maven-v4_0_0.xsd" gefunden werden kann das scheint wahr zu sein. –

Antwort

5

Streifen mit der Namespace in pom.xml

gegeben sed:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
</project> 

dies:

cat pom.xml | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' - 

gibt diese:

<modelVersion>4.0.0</modelVersion> 

wenn Sie funky Formatierung haben (wie die xmlns Attribute auf ihre eigenen Linien sind), ist es durch den Formatierer laufen zuerst:

cat pom.xml | xmllint --format - | sed '2 s/xmlns=".*"//g' | xmllint --xpath '/project/modelVersion' - 
+0

Danke, habe das gerade gesehen. Ich habe die Xmlns Attribute über mehrere Zeilen verteilt, '--format' könnte eine gute Lösung dafür sein –

1
xmllint --xpath "/*[local-name() = 'project']/*[local-name() = 'parent']/*[local-name() = 'version']/text()" pom.xml 

Es ist nicht wirklich schön, aber es Formatierung vermeiden Annahmen und/oder Neuformatierung der Eingabe pom.xml-Datei.

Wenn Sie den "-SNAPSHOT" aus irgendeinem Grund entfernen müssen, leiten Sie das Ergebnis des obigen durch | sed -e "s|-SNAPSHOT||".