2012-01-26 25 views
6

Mam typowy pom.xml i chcę wydrukować identyfikator groupId, artifactId i wersję, oddzielone dwukropkiem. Myślę, że XMLStarlet jest odpowiednim narzędziem do tego. Próbowałem na kilka sposobów, ale zawsze otrzymuję pustą linię.XMLStarlet niczego nie wybiera

xml sel -t -m project -v groupId -o : -v artifactId -o : -v version pom.xml 

oczekiwany wynik:

org.something.apps:app-acct:5.4 

Prawdziwe wyjście: pusta linia

Nawet jeśli próbuję wydrukować tylko GroupID mam nic:

Jestem pewien, że narzędzie widzi elementy, ponieważ mogę je bez problemu wymienić:

xml el pom.xml 

drukuje następujące (poprawnie):

project 
project/modelVersion 
project/parent 
project/parent/groupId 
project/parent/artifactId 
project/parent/version 
project/groupId 
project/artifactId 
project/version 
project/packaging 

Co się stało?

Oto wersja cut-dół pom.xml:

<?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> 

    <parent> 
     <groupId>org.something</groupId> 
     <artifactId>base</artifactId> 
     <version>1.16</version> 
    </parent> 

    <groupId>org.something.apps</groupId> 
    <artifactId>app-acct</artifactId> 
    <version>5.4</version> 
    <packaging>war</packaging> 

</project> 

Odpowiedz

28

Niestety XMLStarlet jest bardzo wybredna w domyślnej przestrzeni nazw. Jeśli dokument ma ona zadeklarowana (xmlns=), trzeba uznać je za zbyt XMLStarlet i prefiks elementy z nazwą wybranej (patrz here):

xml sel -N mój = http://maven.apache.org/POM/4.0.0 -t - m mój: projekt -v moim: GroupID -o: -v moje: artifactId -o: -v moja wersja pom.xml

Uruchomienie powyższego polecenia daje oczekiwany wynik:

org.something.apps:app-acct:5.4 

Jednakże, jeśli dokument NIE ma de zadeklarowana przestrzeń nazw (lub przestrzeń nazw ma nieco inny URL), powyższe polecenie NIE działa, co jest prawdziwym PITA. Bardziej uniwersalnym rozwiązaniem jest usunięcie domyślnej deklaracji przestrzeni nazw przed wybraniem elementów. Od XMLStarlet 1.3.1 konwertowanie formatu XML na format PYX i powrót usuwa deklaracje przestrzeni nazw:

xml pyx pom.xml | xml p2x | xml sel -t -m projekt -v GroupID -o: -v artifactId -o: -v wersja 2> nul

UPDATE (12.02.2014): jak z XMLStarlet 1.4.2 pyx < -> Konwersja XML jest poprawiona (nie usuwa deklaracji przestrzeni nazw), więc powyższe polecenie NIE będzie działać (podziękowania dla Petera Glucka za podpowiedź). Zamiast tego użyj następującego polecenia:

xml pyx pom.xml | grep -v^A | xml p2x | xml sel -t -m projektu -v GroupID -o: -v artifactId -o: wersja -v

Uwaga: powyżej grep usuwa wszystkie atrybuty z dokumentu, a nie tylko deklaracje przestrzeni nazw. W tym konkretnym przypadku (wybierając wartości elementów z pom.xml, gdzie nie są oczekiwane elementy z domyślnymi przestrzeniami nazw) jest OK, ale dla ogólnego XML usuwałbyś tylko domyślne deklaracje przestrzeni nazw i nic więcej:

xml pyx pom.xml | grep -v "^ Axmlns" | xml p2x | XML Sel -t -m projekt -v GroupID -o: -v artifactId -o: wersja -v


Note (przestarzałe): przekierowanie błędu (2>nul) jest konieczne, aby ukryć skargę o (obecnie) nieznany nazw xsi:

-: 1.28: przedrostek nazw xsi dla schemaLocation nad projektem nie jest zdefiniowana

Innym sposobem na pozbycie reklamacji jest usunięcie schemaLocation na tribute (w rzeczywistości to polecenie usuwa wszystkie atrybuty z dokumentu PYX, a nie tylko xsi: schemaLocation):

xml pyx pom.xml | grep -v^A | xml p2x | XML Sel -t -m projekt -v GroupID -o: -v artifactId -o: wersja -v

+0

Twoja komentarz na temat przedrostków elementów z (alias dla?) Zadeklarowanej przestrzeni nazw jest zasadniczą różnicą dla połączonych dokumentów. – chernevik

5

XML-> pyx -> XML sztuczka nie działa dla mnie (wersja 1.4.2 za pomocą XMLStarlet) . Jednak XMLStarlet documentation zawiera ten poręczny sed komenda usuwa deklaracji przestrzeni nazw z dokumentu XML:

sed -e 's/ xmlns.*=".*"//g' 

To działało. W przypadku pytania oryginalnego składnia byłaby:

cat pom.xml | sed -e 's/ xmlns.*=".*"//g' | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version 
+0

Dziękujemy za aktualizację dotyczącą zmiany konwersji PYX -> XML. Oznacza to, że ostatnia linia poleceń (z grep -v^A) jest teraz preferowana. Jednakże, sed/grep/awk itp. NIE powinien być używany w ogólnym XML: działa na tym konkretnym prostym przykładzie w dokumentacji (i na moim uproszczonym przykładzie), ale może łatwo stworzyć nieprawidłowy dokument XML. Przykład: uruchomienie tego "poręcznego" sed na tym: a = "X"; return a; spowoduje to: uk4sx