2010-08-04 69 views
0

我需要解析數據庫中的XML文檔並搜索其中的給定表達式。然後,如果給定的表達式存在於XML中,我必須返回一個String值,否則我需要通過下一個表達式解析並返回另一個String值等等。在XPath表達式中使用條件

// An xml document is passed as a Node when getEntryType() method is called 

public static class XMLTextFields { 
     public static String getEntryType(Node target) throws XPathExpressionException { 
      XPathFactory factory = XPathFactory.newInstance(); 
      XPath xpath = factory.newXpath(); 
      String entryType = null; 
      String [] expression = new String [] {"./libx:package", "./libx:libapp", "./libx:module"}; 

      String [] type = new String [] {"Package", "Libapp", "Module" }; 
      for (int i = 0; i < 3; i ++) { 
       XPathExpression expr = xpath.compile(expression[i]); 
       Object result = expr.evaluate(target, XPathConstants.NODESET); 
       NodeList nodes = (NodeList) result; 
       if (nodes.getLength() == 0) 
        continue; 
       entryType = (type[i]); 
      } 
      return entryType; 
     } 
    } 

我想知道是否有一個更簡單的方式做到這一點:

我用下面的代碼實現這一點?意思是,有沒有一種方法可以像使用「表達式」一樣的函數返回一個字符串,如果表達式存在於xml中的話。

我猜我應該可以做這樣的事情,但我不能完全確定:如果libx中

String [] Expression = new String [] {"[./libx:package]\"Package\"", ....} 

意義,迴歸「大禮包」:在給定的XML存在包節點

回答

0

@ALL:謝謝!

我使用:

XPathExpression EXPR = xpath.compile( 「CONCAT(子串( '包',0100 *布爾型(// libx中:封裝)),」 +「的子串( 'Libapp',0100 *布爾(// libx中:libapp)),子( '模塊',0100 *布爾型(// libx中:模塊)))「); expr.evaluate(target,XPathConstants.STRING);

+0

我正在使用XPath處理器版本1,所以這似乎是最合適的。 – sony 2010-09-21 03:57:24

0

是有,只是在你的表達式中使用XPath函數:

Expression exp = xpath.compile("local-name(*[local-name() = 'package'])") 
// will return "package" for any matching elements 
exp.evaluate(target, XPathConstants.STRING); 

但這將返回,而不是「包」,「包」。注意大寫的P

下面是測試代碼:

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathExpression; 
import javax.xml.xpath.XPathExpressionException; 
import javax.xml.xpath.XPathFactory; 
import org.w3c.dom.Document; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 

import java.util.Map; 
import java.util.HashMap; 

public class Test { 
     private static Map<String, String> mappings = new HashMap<String, String>(); 
     static { 
      mappings.put("package", "Package"); 
      mappings.put("libapp", "Application"); 
      mappings.put("module", "Module"); 
     } 

     public static void main(String[] args) throws Throwable { 
      XPathFactory factory = XPathFactory.newInstance(); 
      XPath xpath = factory.newXPath(); 
      String entryType = null; 
      XPathExpression [] expressions = new XPathExpression[] { 
      xpath.compile("local-name(*[local-name() = 'package'])"), 
      xpath.compile("local-name(*[local-name() = 'libapp'])"), 
      xpath.compile("local-name(*[local-name() = 'module'])") 
      }; 

      DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder parser = fac.newDocumentBuilder(); 
      Document doc = parser.parse(args[0]); 

      for(int i = 0; i < expressions.length; i++) { 
      String found = (String) expressions[i].evaluate(doc.getDocumentElement(), 
          XPathConstants.STRING); 
      entryType = mappings.get(found); 
      if(entryType != null && !entryType.trim().isEmpty()) { 
       break; 
      } 
      } 

      System.out.println(entryType); 

     } 
} 

文本文件的內容:

<?xml version="1.0"?> 
<root xmlns:libx="urn:libex"> 
    <libx:package>mypack</libx:package> 
    <libx:libapp>myapp</libx:libapp> 
    <libx:module>mymod</libx:module> 
</root> 
+0

謝謝!我的xml文檔包含libx:package,libx:libapp或libx:module(NOT ALL THREE)。所以,當local-name()函數返回空時,我會繼續,否則我會從循環中斷開。現在,entryType字符串將具有適當的字符串。 但是,字符串entryType應該是「Package」而不是「package」。 (注意大寫P)。這是必要的!有沒有辦法做到這一點?請在下面的評論中看到我的測試代碼: – sony 2010-08-04 16:46:00

+0

getEntryType(..){........ String [] expression = new String [] {「local-name(* [local-name()=' (local name)(* [local-name()='module'])「};對於(int i = 0; i sony 2010-08-04 16:48:55

+0

您的代碼似乎是正確的,但不需要在每次調用該方法時編譯表達式。我已經更新了代碼以返回一個不同的字符串,如果找到一個元素。我已經將元素名稱映射到「用戶firendly名稱」。 – naikus 2010-08-04 17:53:17

0

你可以在這裏使用XSLT。在XSLT您可以使用

<xsl:value-of select="*[starts-with(name(),'libx:package')]" />

檢查節點名,也可以使用檢查

<xsl:if select="name()='libx:package'" > <!-- Your cusotm elements here... --> </xsl:if>

您可以檢查元素的存在和屬性這種方式來驗證特定需求。

希望這有助於。

0

在XPath 1.0

concat(translate(substring(local-name(libx:package|libx:libapp|libx:module), 
          1, 
          1), 
       'plm', 
       'PLM'), 
     substring(local-name(libx:package|libx:libapp|libx:module),2)) 

編輯:這是難治,因爲沒有提供輸入樣本瞭解路徑...