Xml xpath根据子级的属性值删除节点
我有以下xml代码:Xml xpath根据子级的属性值删除节点,xml,xslt,xpath,attributes,Xml,Xslt,Xpath,Attributes,我有以下xml代码: <osm> <count> <tag k="nodes" v="608"/> </count> <node> <tag k="addr:housenumber" v="5-10"/> <tag k="addr:postcode" v="BA1 2BX"/> </node> <way> <tag k="am
<osm>
<count>
<tag k="nodes" v="608"/>
</count>
<node>
<tag k="addr:housenumber" v="5-10"/>
<tag k="addr:postcode" v="BA1 2BX"/>
</node>
<way>
<tag k="amenity" v="nightclub"/>
<tag k="facebook" v="https://www.facebook.com"/>
</way>
<node>
<tag k="amenity" v="cafe"/>
<tag k="addr:postcode" v="BS3 2BX"/>
</node>
<node>
<tag k="amenity" v="school"/>
<tag k="facebook" v="https://www.facebook.com"/>
</node>
<way>
<tag k="amenity" v="church"/>
<tag k="addr:postcode" v="BAX 5RT"/>
</way>
</osm>
我尝试了许多关于此查询的排列,但它会返回以下情况的每次出现:
我想我需要找到父母,但那是我知识枯竭的地方 你是对的;您需要选择标记的父项。为此,只需选择*并将标记放入谓词中 例如
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="osm">
<xsl:copy>
<xsl:apply-templates select="*[not(tag/@k='addr:postcode')]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在此进行工作演示:
或者,您可以添加匹配的模板来代替
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[tag/@k='addr:postcode']"/>
</xsl:stylesheet>
这将产生相同的输出 你是对的;您需要选择标记的父项。为此,只需选择*并将标记放入谓词中 例如
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="osm">
<xsl:copy>
<xsl:apply-templates select="*[not(tag/@k='addr:postcode')]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在此进行工作演示:
或者,您可以添加匹配的模板来代替
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[tag/@k='addr:postcode']"/>
</xsl:stylesheet>
这将产生相同的输出 下面是xpath,用于选择osm下不包含特定标记的所有节点:
//osm/*[not(.//tag[@k='addr:postcode'])]
以下是一些关于不放置的重要注意事项:
搜索不包含任何级别的子元素的元素
以下使用模式:
//element[not(.//child)]
请注意定位器:
将选择至少包含一个id为的子元素的所有元素!=一,
例如:
<row class="row1">
<cell id=1/>
<cell id=2/>
<cell id=3/>
</row>
<row class="row2">
<cell id=1/>
<cell id=2/>
</row>
<row class="row3">
<cell id=1/>
<cell id=2/>
</row>
<row class="row4">
<cell id=3/>
</row>
将选择不包括id为3的单元格的第2行和第3行
//row[.//cell[not(@id=3)]]
将选择行1、2和3,但不选择至少有一个id不是3的单元格的4行
所以,放置not语句的位置很重要,因为它可能会完全改变XPath逻辑。下面是XPath,用于选择osm下不包含特定标记的所有节点:
//osm/*[not(.//tag[@k='addr:postcode'])]
以下是一些关于不放置的重要注意事项:
搜索不包含任何级别的子元素的元素
以下使用模式:
//element[not(.//child)]
请注意定位器:
将选择至少包含一个id为的子元素的所有元素!=一,
例如:
<row class="row1">
<cell id=1/>
<cell id=2/>
<cell id=3/>
</row>
<row class="row2">
<cell id=1/>
<cell id=2/>
</row>
<row class="row3">
<cell id=1/>
<cell id=2/>
</row>
<row class="row4">
<cell id=3/>
</row>
将选择不包括id为3的单元格的第2行和第3行
//row[.//cell[not(@id=3)]]
将选择行1、2和3,但不选择至少有一个id不是3的单元格的4行
所以,放置not语句的位置很重要,因为它可能会完全改变XPath逻辑