有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在Xpath中使用大写或匹配

我已经查看并尝试了给出的解决方案,但我无法找到任何适合我的xpath的解决方案。通过Tomcat7使用Java7(通过JSP页面) 以下是我的示例XML:

<table name='phonebook'>
<record>
    <field name='fname'>John</field>
    <field name='lname'>Dee</field>
    <field name='City'>London</field>
    <field name='Phone'>020123</field>
</record>
<record>
    <field name='fname'>JOHN</field>
    <field name='lname'>Smith</field>
    <field name='City'>london</field>
    <field name='Phone'>020456</field>
</record>
<record>
    <field name='fname'>Marble</field>
    <field name='lname'>SMith</field>
    <field name='City'>Bristol</field>
    <field name='Phone'>0117123</field>
</record>
</table>
</database>

我有一个搜索(工作正常),但它是区分大小写的。请注意,我用不同的大小写拼写了John、London和Smith,我希望在搜索时匹配这些大小写。 那么,如何在感性搜索中找到他们的案例呢? 以下是我的Java/XPATH:

XPathExpression expr = xpath.compile("//table[@name='phonebook']/record[upper-case(field[@name='fname'])='JOHN']");

所以这里我想找到所有fname值为JOHN的记录,不管大小写。 它给了我一个javax。xml。xpath。XPathExpressionException。 当我去掉“大写(……”)它可以工作(但区分大小写)。 我也尝试过“match()”但没有成功


共 (2) 个答案

  1. # 1 楼答案

    XPath 1.0中没有upper-case函数。但是,Java的XPath API允许您定义自己的函数:

    XPathFunction upperCase = new XPathFunction() {
        @Override
        @SuppressWarnings("rawtypes")
        public Object evaluate(List args) {
            StringBuilder text = new StringBuilder();
    
            for (Object arg : args) {
                NodeList list = (NodeList) arg;
    
                int len = list.getLength();
                for (int i = 0; i < len; i++) {
                    Node node = list.item(i);
                    String s = node.getTextContent();
                    if (s != null) {
                        text.append(s.toUpperCase());
                    }
                }
            }
    
            return text.toString();
        }
    };
    
    xpath.setXPathFunctionResolver((f, count) ->  {
        return "upper-case".equals(f.getLocalPart()) ? upperCase : null;
    });
    
    XPathExpression expr = xpath.compile("//table[@name='phonebook']/record[dummy:upper-case(field[@name='fname'])='JOHN']");
    

    注意,我在XPath表达式中的upper-case中添加了一个虚拟名称空间前缀。没有命名空间的函数将不会使用XPathFunctionResolver解析

  2. # 2 楼答案

    这是来自javax的文档。xml。xpath:

    Package javax.xml.xpath Description

    This package provides an object-model neutral API for the evaluation of XPath expressions and access to the evaluation environment.

    The following XML standards apply:

    XML Path Language (XPath) Version 1.0

    upper-case函数不是该XPath规范的一部分

    但是,您可以使用如下所示的解决方法:

    Object result = (Object) xpath.evaluate("//table[@name='phonebook']/record[field[@name='fname']]", xml, XPathConstants.NODESET);
    if ( result != null && result instanceof NodeList )
    {
        NodeList nodeList = (NodeList)result;
        List<Node> filteredList = new ArrayList<Node>();
        if ( nodeList.getLength() > 0 )
        {
            for ( int i = 0; i < nodeList.getLength(); i++ )
            {
                Node recordNode = nodeList.item( i );
                NodeList list = recordNode.getChildNodes();
                for ( int j = 0 ; j < list.getLength(); j++ )
                {
                     Node fName = list.item(j);
                     if ( fName.getNodeType() == Element.ELEMENT_NODE )
                     {
                          Element fNameElem = (Element)fName;
    
                          String nameAttr = fNameElem.getAttribute( "name" );
                          if ( nameAttr != null && nameAttr.equals( "fname" ) && fNameElem.getTextContent() != null && fNameElem.getTextContent().equalsIgnoreCase("JOHN") )
                          {
                             filteredList.add( recordNode );
                             break;
                          }
                     }
                 }
            }
        }
    }
    

    使用xpath查找具有属性为name='fname'fieldrecord元素,并遍历这些元素,删除那些没有文本内容的元素,如JOHN,忽略大小写