Xpath工厂不考虑所有(可能)并发命名空间

时间:2013-08-08 08:40:41

标签: java xml xpath xml-namespaces

我有一个问题*关于使用无前缀命名空间和带前缀('video')的标准命名空间解析xml文件:我总是在所有带有“视频”前缀的标签上为空... 我已经对同一个文件的多个前缀做了同样的事情,这样就可以了。  我只是遇到了那个问题...而且因为这也是我第一次使用“无前缀”命名空间,我不确定这个问题是来自这个无前缀的命名空间,还是来自视频的命名空间。< / p>

以下是一些示例:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
  <url>
    <loc>http://www.dailymotion.com/video/xtx3pa_decouvrez-l-onyx-voiture-des-reves-de-peugeot_news</loc>
    <video:video>
      <video:player_loc allow_embed="yes">http://www.dailymotion.com/swf/video/xtx3pa?autoPlay=1</video:player_loc>
      <video:title>Découvrez l'Onyx, voiture des rêves de Peugeot</video:title>
      <video:description>Révélée au Mondial de l'Automobile ce matin, la dernière concept-car du constructeur a fait sensation.</video:description>
      <video:publication_date>1348768884</video:publication_date>
      <video:tag>mondial</video:tag>

      <video:category>news</video:category>
      <video:language>FR</video:language>
    </video:video>
  </url>
  <url>  ...</url>...

以下是我使用的代码,以下示例here

  static public class MyNamespaceContext implements NamespaceContext {
     final private Map<String, String> prefixMap;
     MyNamespaceContext(Map<String, String> prefixMap)
     {
         if (prefixMap != null)
         {
             this.prefixMap = Collections.unmodifiableMap(new HashMap<String, String>(prefixMap));
         }
         else
         {
             this.prefixMap = Collections.emptyMap();
         }
     }
     public String getPrefix(String namespaceURI) {
         // TODO Auto-generated method stub
         return null;
     }
     public Iterator getPrefixes(String namespaceURI) {
         // TODO Auto-generated method stub
         return null;
     }
     public String getNamespaceURI(String prefix) {
             if (prefix == null) throw new NullPointerException("Invalid Namespace Prefix");
             else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX))
                 return "http://www.sitemaps.org/schemas/sitemap/0.9";
             else if ("video".equals(prefix))
                 return "http://www.google.com/schemas/sitemap-video/1.1";
             else    
                 return "http://www.sitemaps.org/schemas/sitemap/0.9";
     }


 }

XPathFactory fabrique = XPathFactory.newInstance();
xpath = fabrique.newXPath();
xpath.setNamespaceContext(new MyNamespaceContext(null));
final String videosPath = "//urlset/url";
try{
    XPathExpression exp = xpath.compile(videosPath);
    videoLists = (NodeList)exp.evaluate(inDoc,XPathConstants.NODESET);
}catch(XPathExpressionException e){
    logger.info("oops",e);
    }
for(int i=0; i<videoLists.getLength(); i++){
    Node node = videoLists.item(i);
    XPathExpression exp = xpath.compile("video:video/video:title");
        String title = exp.evaluate((Element)node);
        XPathExpression exp2 = xpath.compile("loc");
        String loc = exp2.evaluate((Element)node);

        logger.info("title  : " +title); // => null
        logger.info("loc : " + loc); => http://www.dailymotion.com/swf/video/xtx3pa?autoPlay=1
}

(*)(更不用说,我是DOM / xpath /中的完美初学者)等等。

1 个答案:

答案 0 :(得分:0)

您尚未显示XPath表达式。在XPath 1.0中,没有前缀总是表示没有名称空间。如果要访问命名空间中的节点(甚至是默认的名称空间),则必须在XPath表达式中使用带前缀的名称。您不能使用NamespaceContext将“null前缀”映射到命名空间,因为XPath规范不允许它。

为什么不转向更灵活的XPath 2.0?它在Java中得到了很好的支持,例如Saxon库。 XPath 1.0已经过时多年了。