Java 在XPath表达式中使用条件

Java 在XPath表达式中使用条件,java,xml,xpath,Java,Xml,Xpath,我需要解析数据库中的XML文档,并在其中搜索给定的表达式。然后,如果给定的表达式存在于XML中,我必须返回一个字符串值,否则我需要解析下一个表达式并返回另一个字符串值,依此类推 我通过使用以下代码实现了这一点: // An xml document is passed as a Node when getEntryType() method is called public static class XMLTextFields { public static String g

我需要解析数据库中的XML文档,并在其中搜索给定的表达式。然后,如果给定的表达式存在于XML中,我必须返回一个字符串值,否则我需要解析下一个表达式并返回另一个字符串值,依此类推

我通过使用以下代码实现了这一点:

// 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:Package节点,则返回Package如果XPath处理器是版本2,则可以使用if表达式:。

是的,只需在表达式中使用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>

您可以在这里使用XSLT。在XSLT中,可以使用

或者您可以使用

您可以通过这种方式检查元素或属性是否存在,以验证特定需求

希望这有帮助。

在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))
编辑:很难理解路径,因为没有提供输入示例…

@ALL:谢谢

我用过:

XPathExpression expr=xpath.compileconcatsubstring'Package',0100*布尔//libx:Package,+子字符串'Libapp',0100*布尔//libx:Libapp,子字符串'Module',0100*布尔//libx:Module;
expr.evaluatetarget,XPathConstants.STRING

谢谢!我的xml文档包含libx:package、libx:libapp或libx:moduleno这三个部分。所以,当本地名称函数返回空时,我执行continue,否则我将中断循环。现在,entryType字符串将具有相应的字符串。但是,字符串entryType应该是Package而不是Package。注意大写字母P。这是必要的!有办法吗?请在下一条注释中查看我的测试代码:getEntryType。。{…….字符串[]表达式=新字符串[]{local name*[local name='package'],local name*[local name='libapp'],local name*[local name='module']};forint i=0;i您的代码似乎是正确的,但无需在每次调用该方法时编译表达式。我已更新代码,以便在找到元素时返回不同的字符串。我保留了元素名称到用户名的映射。我使用的是XPath处理器版本1,因此这似乎是最合适的。
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))