我想学习如何在xml文件中搜索单词并使用xslt删除整行
实施例: abc.xml
<server>
<mbean code="org.jboss.varia.property.SystemPropertiesService"
name="abc.props:type=Service,name=abcprop">
<attribute name="Properties">
abc.def.ghi=123
ghi.klm.nop=123
qrst.tuv.wxy=123
zab.cde.fgh=123
ijk.lmn.opq=remove
rst.uvw.xyz=123
abc.tuv.nop=123
ajc.dzf.goi=123
</attribute>
</mbean>
</server>
从上面的示例中,我想搜索“删除”字样并删除完整的一行:ijk.lmn.opq=remove
预期输出为:
<server>
<mbean code="org.jboss.varia.property.SystemPropertiesService"
name="abc.props:type=Service,name=abcprop">
<attribute name="Properties">
abc.def.ghi=123
ghi.klm.nop=123
qrst.tuv.wxy=123
zab.cde.fgh=123
rst.uvw.xyz=123
abc.tuv.nop=123
ajc.dzf.goi=123
</attribute>
</mbean>
</server>
更新
我尝试了以下代码
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[(@* != 'DELETE')]"/>
</xsl:stylesheet>
有些它无法正常工作,它会删除xml文件中的所有内容并显示一个空文件。
答案 0 :(得分:4)
如果你坚持使用XSLT 1.0,你可以使用它:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--String replace template-->
<xsl:template name="removeline">
<xsl:param name="string" />
<xsl:choose>
<xsl:when test="contains($string,'remove')">
<xsl:variable name="before">
<xsl:value-of select="substring-before($string,'remove')"/>
</xsl:variable>
<xsl:variable name="after">
<xsl:value-of select="substring-after($string,'remove')"/>
</xsl:variable>
<xsl:value-of select="substring($before,1, string-length($before) - 12)"/>
<xsl:call-template name="removeline">
<xsl:with-param name="string" select="$after" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- copy all nodes -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- copy text nodes, and apply removeline template -->
<xsl:template match="text()" >
<!-- create empty string for match -->
<xsl:variable name="empty_string"/>
<xsl:if test="normalize-space(.) != $empty_string">
<xsl:call-template name="removeline">
<xsl:with-param name="string" select="normalize-space(.)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
您可以在此处看到三个模板。第一个是XSLT 1.0的字符串函数替换,没有。它基于在网的几个地方发现的一个。您可以在https://stackoverflow.com/a/7523245/2657945中找到更通用的实现方法。
第二个和第三个模板在获取文档时输出文档中的所有节点和属性,从而形成使用第一个模板处理的文本节点的特殊情况。 这部分基于https://stackoverflow.com/a/427983/2657945中的内容。
输出是这样的(在linux中使用xsltproc):
<server>
<mbean code="org.jboss.varia.property.SystemPropertiesService" name="abc.props:type=Service,name=abcprop">
<attribute name="Properties">abc.def.ghi=123 ghi.klm.nop=123 qrst.tuv.wxy=123 zab.cde.fgh=123 rst.uvw.xyz=123 abc.tuv.nop=123 ajc.dzf.goi=123</attribute>
</mbean>
</server>
这是我能用xml样本生成的最近似的结果,因此根据您的文件和格式,您可能需要再调整一下。
答案 1 :(得分:2)
使用XSLT 2.0,您可以在要操作的文本节点上使用replace
函数:
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node() | @*" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* |node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attribute[@name = 'Properties']/text()">
<xsl:value-of select="replace(., '^.*remove.*$\n*', '', 'm')"/>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
XSLT 1.0只有非常有限的字符串处理功能,因此没有简单的方法来执行纯XSLT的要求。
最好的方法是使用一些用不同语言编写的扩展函数 - 大多数XSLT处理器可以定义和调用这样的扩展函数:Xalan-Java,Saxon,.NET
作为替代方案,考虑不使用XSLT - 考虑到您的问题基本上是字符串匹配而不是XML相关:只需加载XML并使用您喜欢的编程语言处理字符串。