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

时间:2016-10-26 17:41:19

标签: java xpath

我已经查看并尝试了解决方案,但我无法为xpath工作。通过Tomcat7使用Java 7(通过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>

我有一个搜索(工作正常)但它区分大小写。请注意,我用不同的情况拼写了约翰,伦敦和史密斯,我想在搜索时匹配它们。 那么如何通过案例敏感搜索找到它们呢? 这是我的Java / XPATH:

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

所以在这里我想要找到所有具有值为JOHN的fname的记录,而不管大小写。 它给了我一个javax.xml.xpath.XPathExpressionException。 当我拿走'大写(....)'它有效(但区分大小写)。 我也试过'match()'没有成功。

2 个答案:

答案 0 :(得分:1)

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

  

包javax.xml.xpath说明

     

此软件包为评估提供了对象模型中性API   XPath表达式和对评估环境的访问。

     

以下XML标准适用:

     

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查找record具有属性field的{​​{1}}元素并迭代这些元素并删除那些没有文本内容为name='fname'的元素无视案例

答案 1 :(得分:0)

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不会解析没有命名空间的函数。