/ / Usuń przestrzeń nazw z xmlstarlet output - xml, xpath, namespaces, xmlstarlet, xmllint

Usuń przestrzeń nazw z xmlstarlet wyjście - xml, obszary nazw i xmlstarlet, xpath: xmllint

Szukasz ekstraktów z następujących treści XML:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:inputText id="id"/>
...
</ui:composition>

Ekstrakcja

Wszystko h:inputText elementy można wybrać za pomocą:

xmlstarlet sel -t -c "//h:inputText" filename.xml

Problem

W wyniku tego powstaje następujący wynik:

<h:inputText
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets" id="id"/>

Pytanie

W jaki sposób można wyłączyć obszary nazw z danych wyjściowych?

Pomysły

Używaj wyrażeń regularnych do postprocessingu; jednak:

  • sed nie ma nie-chciwego pojedynku;
  • perl jest zbyt ciężki (i wymagałoby złożonego wyrażeń regularnych).

Ruruj przez xmllint lub xmlstarlet dla drugiego przebiegu, ale to wymaga dobrze sformułowanego dokumentu XML.

Użycie xmllint stwarza własny zestaw problemów z przestrzeniami nazw.

Wytwórz dokument składający się tylko z ui:composition i h:inputText elementy:

<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:inputText id="id"/>
<h:inputText id="id"/>
</ui:composition>

Jest to trudne, ponieważ h:inputText elementy mogą występować na dowolnej głębokości dokumentu.

Odpowiedzi:

1 dla odpowiedzi № 1

Możesz użyć XSLT. Jeśli chcesz wydrukować h:inputText Tak jak jest, nie będziesz w stanie powstrzymać deklaracji przestrzeni nazw wiążącej prefiks h: do uri http://java.sun.com/jsf/html.

XSLT 1.0

Stwórz input.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:h="http://java.sun.com/jsf/html">
<xsl:output omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
<xsl:apply-templates select="//h:inputText"/>
</xsl:template>

<xsl:template match="h:inputText">
<xsl:copy>
<xsl:copy-of select="@*"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

xmlstarlet command

xmlstarlet tr input.xsl filename.xml

Wydajność

<h:inputText xmlns:h="http://java.sun.com/jsf/html" id="id"/>

Możesz wydrukować inputText w żadnym obszarze nazw ...

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:h="http://java.sun.com/jsf/html" exclude-result-prefixes="h">
<xsl:output omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
<xsl:apply-templates select="//h:inputText"/>
</xsl:template>

<xsl:template match="h:inputText">
<inputText>
<xsl:copy-of select="@*"/>
</inputText>
</xsl:template>

</xsl:stylesheet>

Wydajność

Używanie tego samego wiersza poleceń powyżej:

<inputText id="id"/>

Uwaga: może być konieczne dodanie <xsl:text>&#xA;</xsl:text> po </xsl:copy> (lub </inputText> w drugim przykładzie), aby jawnie dodać znak nowej linii. W przeciwnym razie xmlstartlet może wyprowadzać wszystkie elementy w jednym wierszu. (Zrobiłem to dla mnie używając xmlstarlet 1.6.1 i indent="yes" na xsl:output nie pomogło.)

Wyjście JSF

Ponieważ JSF jest zaangażowany, rozważ:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
exclude-result-prefixes="h f c ui a4j">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>

<xsl:template match="/">
<h:html>
<xsl:apply-templates select="//h:inputText"/>
</h:html>
<xsl:text>&#xA;</xsl:text>
</xsl:template>

<xsl:template match="h:inputText">
<xsl:text>&#xA;</xsl:text>
<h:inputText>
<xsl:copy-of select="@*"/>
</h:inputText>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>