【发布时间】:2017-03-25 01:17:18
【问题描述】:
背景
希望从以下 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>
提取
所有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 元素可以出现在文档的任何深度。
【问题讨论】:
标签: xml xpath namespaces xmlstarlet xmllint