2016-11-10 4 views
1

фон

Глядя извлечь элементы из следующего содержания XML:Удаление имен с выхода XMLStarlet

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

Extraction

Всех h:inputText элементов может быть выбран с помощью:

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

Задача

Это производит следующие пространства имен кишащего выход:

<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"/> 

Вопрос

Как пространства имен быть подавлены с выхода?

Идеи

Использование регулярных выражений для последующей обработки; однако:

  • sed не имеет неживого соответствия;
  • perl слишком тяжеловес (и для него потребуется сложное регулярное выражение).

Проложить через xmllint или xmlstarlet для второго прохода, но для этого требуется хорошо сформированный XML-документ.

Использование xmllint создает свой собственный набор проблем с пространством имен.

Подготовить документ, состоящий только из ui:composition и h:inputText элементов:

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

Это сложно, так как h:inputText элементы могут иметь место на любой глубине документа.

ответ

1

Вы можете использовать XSLT. Если вы хотите вывести h:inputText as-is, вы не сможете запретить объявление пространства имен, связывающее префикс h: с uri http://java.sun.com/jsf/html.

XSLT 1,0

Создать 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

xmlstarlet tr input.xsl filename.xml 

Выход

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

Вы можете выводить inputText в отсутствии пространства имен, хотя ...

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> 

Выход

Используя ту же командную строку выше:

<inputText id="id"/> 

Примечание: Возможно, потребуется добавить <xsl:text>&#xA;</xsl:text> после </xsl:copy> (или </inputText> во втором примере), чтобы явно добавить новую строку. В противном случае xmlstartlet может выводить все элементы в одной строке. (. Это было для меня, используя XMLStarlet 1.6.1 и indent="yes" на xsl:output не помогло)

JSF Выход

Поскольку JSF занимается, считают:

<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> 
+0

Не уверен, что JSF должен сделать с чем угодно, но если ваше редактирование поможет вам, я не откажусь. –

Смежные вопросы