2016-10-26 14 views
0

私は見た上で解決策を試しましたが、私のxpathで動作するようにはできません。 Javaの7 Tomcat7から(JSPページから) を使用すると、ここに私のサンプルXMLです: Xpathでの大文字または小文字の使用方法

<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のfnameのを持つすべてのレコードを検索したい

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

: はここに私のJava/XPATHです。 それは私にjavax.xml.xpath.XPathExpressionExceptionを与えます。 「大文字(....)」を取り除くと、大文字と小文字が区別されます。 私も 'match()'を試してみましたが、成功しませんでした。

+0

'upper-case 'はXPathの標準関数ですか?私は[仕様](https://www.w3.org/TR/xpath/#section-String-Functions)に記載されていません。 – VGR

+0

大文字と小文字を区別しないxpath contains()は可能ですか?(http://stackoverflow.com/questions/8474031/case-insensitive-xpath-contains-possible)(同じcase-insensitve技術は 'contains()'なしで動作します。 ) – kjhughes

+0

'upper-case()'がXPath 2.0を必要とする – kjhughes

答えて

1

これはjavax.xml.xpathののドキュメントからです:

パッケージjavax.xml.xpathの説明このパッケージは、XPathの評価 ためのオブジェクトモデルに依存APIを提供し

評価環境へのアクセスを提供します。

次のXML標準が適用されます。

XML Path Language (XPath) Version 1.0

upper-case機能は、そのXPath仕様の一部ではありません。

以下に示すように、あなたが回避策を使用することができますしかし

:属性name='fname'fieldを持ってrecord要素を探し、それらの要素を反復処理してテキストコンテンツを持っていないものを削除する

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 JOHNとして無視する

+0

JSPページで 'javax.xml.xpath。*'をロードしています。それはXPATH v2ではないのですか?そうでなければ、xpath v2をロードできますか? – mljm

+0

@mjlmでは、javax.xml.xpathはxpath 1.0に基づいています。 xpath 2.0を利用したい場合は、サクソニカのようなサードパーティのライブラリが役に立ちます。 http:// stackoverflowを見てみてください。com/questions/6624149/xpath-2-0-for-java-possible – SomeDude

+0

回避策が動作します、ありがとう!私のコードの別の部分はNodeListを期待していましたので、新しいNodeListで結果を取得しようとしましたが、それは見た目ほど単純ではないことがわかりました。そこで、リストを受け入れるように他の部分を変更しました。まだコアのXPathで大文字/小文字を持たないのは少し間違っているようですが、少なくともXPath-testerがエラーを出さなかった理由を説明します.XPath2を使用すると、 – mljm

0

XPath 1.0には、upper-caseという機能はありません。私は、XPath式でupper-caseにダミーの名前空間接頭辞を追加

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']"); 

注意:ただし、JavaのXPathのAPIを使用して、独自の関数を定義することができます。名前空間のない関数はXPathFunctionResolverでは解決されません。

関連する問題