2010-08-04 2 views
0

Мне нужно проанализировать XML-документ в базе данных и найти в нем заданное выражение. Затем я должен вернуть значение String, если данное выражение присутствует в XML else, мне нужно проанализировать следующее выражение и вернуть другое значение 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.

Я предполагаю, что я должен быть в состоянии сделать что-то подобное, но я не совсем уверен:

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

Значение, возвращение «Пакет», если libx: пакет узел существует в данном XML

ответ

0

@ALL: Спасибо!

я использовал:

XPathExpression выр = xpath.compile ("CONCAT (подстрока ('пакет', 0100 * булево (// libx: пакет))," + «подстрока ('Libapp', 0100 * булево (// libx: libapp)), подстрока ('модуль', 0100 * булево (// libx: модуль))) "); expr.evaluate (цель, XPathConstants.STRING);

+0

Я использую процессор XPath версии 1, поэтому это, по-видимому, лучше всего подходит. – sony

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 должна быть «Пакет», а не «пакет». (Обратите внимание на капитал P). Это необходимо! Есть ли способ сделать это? Посмотрите мой тестовый код в следующем комментарии: – sony

+0

getEntryType (..) {........ String [] expression = new String [] {"local-name (* [local-name() = ' package ']) "," local-name (* [local-name() =' libapp ']) "," local-name (* [local-name() =' module ']) "}; for (int i = 0; i <выражение.length; i ++) { XPathExpression expr = xpath.compile (выражение [i]); entryType = (String) expr.evaluate (target, XPathConstants.STRING); if (entryType.isEmpty()) continue; break; } return entryType; } Возможно, я хочу вернуть «Это пакет», а не «пакет» – sony

+0

Ваш код кажется правильным, но не нужно компилировать выражения для каждого вызова метода. Я обновил код, чтобы вернуть другую строку, если элемент найден. Я сохранил сопоставление имен элементов с именами «user firendly». – naikus

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)) 

EDIT: Это было dificult понять путь, потому что не был обеспечен ввод образца ...

Смежные вопросы