2012-11-05 87 views
0

下面是XMLXPath表達式輸出父節點和匹配的子節點排除無與倫比的子節點

<?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作爲轉換輸出。相反,我只需要在父節點+子節點匹配撰文/值=「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

我懷疑你可以用'XSL做到這一點:禁止複製的'和一個XPath。你將不得不使用更復雜的樣式表(但XPath表達式會更令人愉快)。這是你的整個XSLT? – toniedzwiedz

+0

@Tom其實即時通過使用java程序來評估xpath表達式來獲得我想要的XML輸出。所以我請求了一個xpath擴展。以下是我的Java代碼 '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節點=(NodeList)結果; ' 請用Java或xslt來幫助我解決正確的解決方案。 – dhinu

回答

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

可否請您在xslt1.0中爲上述實現提供代碼? – dhinu