2011-08-11 4 views
1

XPathを使用して、URL128 XML要素の値だけを取り出しています。私はちょうど以下の例で1つを持っていますが、これらの多くがあることができます。 SearchResponse要素にxmlns = 'http://c1.net.corbis.com/'を含めると、空のNodeListが取得されますが、その名前空間要素を削除すると正常に動作します。私が紛失している構成はありますか?XPathネームスペース宣言の解析

String xmlData = "<SearchResponse xmlns='http://c1.net.corbis.com/'><searchResultDataXML><SearchResultData><SearchRequestUID Scope='Public' Type='Guid' Value='{cded773c-c4b7-4dd8-aaee-8e5b8b7a2475}'/><StartPosition Scope='Public' Type='Long' Value='1'/><EndPosition Scope='Public' Type='Long' Value='50'/><TotalHits Scope='Public' Type='Long' Value='323636'/></SearchResultData></searchResultDataXML><imagesXML><Images><Image><ImageUID Scope='Public' Type='Guid' Value='{a6f6d3e2-2c3f-4502-9741-eae2e1bb573a}'/><CorbisID Scope='Public' Type='String' Value='42-25763849'/><Title Scope='Public' Type='String' Value='Animals figurines'/><CreditLine Scope='Public' Type='String' Value='© Ocean/Corbis'/><IsRoyaltyFree Scope='Public' Type='Boolean' Value='True'/><AspectRatio Scope='Public' Type='String' Value='0.666667'/><URL128 Scope='Public' Type='String' Value='http://cachens.corbis.com/CorbisImage/thumb/25/76/38/25763849/42-25763849.jpg'/></Image></Images></imagesXML></SearchResponse>"; 
      InputSource source = new InputSource(new StringReader(xmlData)); 

      XPath xPath = XPathFactory.newInstance().newXPath(); 
      NodeList list = null; 
      try { 
       list = (NodeList) xPath.evaluate("//URL128/@Value", source, XPathConstants.NODESET); 
      } catch (Exception ex) { 
       System.out.println(ex.getMessage()); 
      } 
      for (int i = 0; i < list.getLength(); i++) { 
       System.out.println(list.item(i).getTextContent()); 
      } 

答えて

2

さて、あなたはXPathNamespaceContextを提供する必要があり、長い物語の短い:

final XPath xPath = XPathFactory.newInstance().newXPath(); 
xPath.setNamespaceContext(new NamespaceContext() { 
    @Override 
    public Iterator<String> getPrefixes(final String namespaceURI) { 
     return null; 
    } 
    @Override 
    public String getPrefix(final String namespaceURI) { 
     return null; 
    } 
    @Override 
    public String getNamespaceURI(final String prefix) { 
     return "http://c1.net.corbis.com/"; 
    } 
}); 
final NodeList list = (NodeList) xPath.evaluate("//c:URL128/@Value", source, XPathConstants.NODESET); 
for (int i = 0; i < list.getLength(); i++) { 
    System.out.println(list.item(i).getTextContent()); 
} 

XPathが、この場合に実装するために私達を必要とする唯一の方法はgetNamespaceURI(String prefix)あるようです。

"c:URL128"の実際のプレフィックスは、この場合はまったく問題ではありません。 ":URL128"と同じように簡単に使用できます。 にXMLに複数の名前空間がある場合、それらの間で区別することが重要になります(比較的少数の要素の場合はMapまたはif-then-elseの系列を使用します)。

あなたができないか、ハードコードには、XML文書からそれらを自分で抽出することができますが、それは少しより多くのコードを必要と接頭辞をしたくない場合は...

は詳細もthis blog post参照してください。以下

+0

これに代わる解決策を見てください... – Adam

0

はAlistairIsrealが概説何実装の2つの方法があります。

あなたはorg.springframework.util.xml.SimpleNamespaceContextインタフェースに頼ることができ、スプリングを使用している場合。単にfalseに設定する名前空間を意識した属性を持つ文書を解析し...あなたのコード内でハードコードされたURI参照を置く伴わないこの、わずかに簡単に解決策があります

InputSource source = new InputSource(new StringReader(unescaped)); 

      XPath xPath = XPathFactory.newInstance().newXPath(); 
      NodeList list = null; 
      try 
      { 
       SimpleNamespaceContext nsCtx = new SimpleNamespaceContext(); 
       nsCtx.bindNamespaceUri("ns", "http://c1.net.corbis.com/"); 
       xPath.setNamespaceContext(nsCtx); 
       list = (NodeList) xPath.evaluate("//ns:URL128/@Value", source, XPathConstants.NODESET); 
      } catch (Exception ex) 
      { 
       System.out.println(ex.getMessage()); 
      } 
      for (int i = 0; i < list.getLength(); i++) 
      { 
       System.out.println(list.item(i).getTextContent()); 
      } 
+0

私の代わりの解決策を見てください... – Adam

1

...

String xmlData = "<SearchResponse xmlns='http://c1.net.corbis.com/'><searchResultDataXML><SearchResultData><SearchRequestUID Scope='Public' Type='Guid' Value='{cded773c-c4b7-4dd8-aaee-8e5b8b7a2475}'/><StartPosition Scope='Public' Type='Long' Value='1'/><EndPosition Scope='Public' Type='Long' Value='50'/><TotalHits Scope='Public' Type='Long' Value='323636'/></SearchResultData></searchResultDataXML><imagesXML><Images><Image><ImageUID Scope='Public' Type='Guid' Value='{a6f6d3e2-2c3f-4502-9741-eae2e1bb573a}'/><CorbisID Scope='Public' Type='String' Value='42-25763849'/><Title Scope='Public' Type='String' Value='Animals figurines'/><CreditLine Scope='Public' Type='String' Value='© Ocean/Corbis'/><IsRoyaltyFree Scope='Public' Type='Boolean' Value='True'/><AspectRatio Scope='Public' Type='String' Value='0.666667'/><URL128 Scope='Public' Type='String' Value='http://cachens.corbis.com/CorbisImage/thumb/25/76/38/25763849/42-25763849.jpg'/></Image></Images></imagesXML></SearchResponse>"; 
InputSource source = new InputSource(new StringReader(xmlData)); 

// create doc instance instead of passing source straight to XPath... 
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
factory.setNamespaceAware(false); // must be false 
DocumentBuilder builder = factory.newDocumentBuilder(); 
final Document doc = builder.parse(source); 

XPath xPath = XPathFactory.newInstance().newXPath(); 

// use doc instead 
NodeList list = (NodeList) xPath.evaluate("//URL128/@Value", doc, 
     XPathConstants.NODESET); 

for (int i = 0; i < list.getLength(); i++) { 
    System.out.println(list.item(i).getTextContent()); 
} 
関連する問題