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 № 1Moż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>
</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>
</xsl:text>
</xsl:template>
<xsl:template match="h:inputText">
<xsl:text>
</xsl:text>
<h:inputText>
<xsl:copy-of select="@*"/>
</h:inputText>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>