下面是XML
<?xml version="1.0" encoding="UTF-8"?>
<library>
<object>book</object>
<bookname>
<value>testbook</value>
<author>
<value>ABCD</value>
<category>
<value>story</value>
<price>
<dollars>200</dollars>
</price>
</category>
</author>
<author>
<value>EFGH</value>
<category>
<value>fiction</value>
<price>
<dollars>300</dollars>
</price>
</category>
</author>
</bookname>
</library>
我需要xpath表达式来获得以下输出
<?xml version="1.0" encoding="UTF-8"?>
<library>
<object>book</object>
<bookname>
<value>testbook</value>
<author>
<value>ABCD</value>
<category>
<value>story</value>
<price>
<dollars>200</dollars>
</price>
</category>
</author>
</bookname>
</library>
但是当我应用下面的xpath表达式时,我将整个输入xml作为转换输出。相反,我只需要父节点+子节点匹配author / value ='ABCD'(如上所示)
<xsl:copy-of select="/library/object[text()='book']/../bookname/value[text()='testbook']/../author/value[text()='ABCD']/../../.."/>
请帮助我使用正确的xpath表达式来获得所需的输出。
我正在使用java程序来评估xpath表达式以获得我想要的XML输出。所以我需要一个xpath表达式。下面是我的java代码
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("books.xml");
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile("/library/object[text()='book']/../bookname/value[text()='testbook']/../author/value[text()='ABCD']/../../..");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
请在 Java或xslt
中帮助我找到正确的解决方案答案 0 :(得分:2)
你不能在纯xpath中执行此操作。
此样式表将在XSL 2.0中执行您想要的操作
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<!-- Idendtity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="author[not(value eq 'ABCD')]"/>
</xsl:stylesheet>
此样式表将在XSL 1.0中执行您想要的操作
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Idendtity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="author[not(value = 'ABCD')]"/>
</xsl:stylesheet>