【问题标题】:Xpath factory does not consider all (maybe)concurrent namespacesXpath 工厂不考虑所有(可能)并发命名空间
【发布时间】:2013-08-08 08:40:41
【问题描述】:

我在解析具有无前缀名称空间和带有前缀('video')的标准名称空间的 xml 文件时遇到问题:我总是在所有带有“video”前缀的标签上得到 null... 我已经对同一个文件的多个前缀做了同样的事情,这没问题。 我只遇到那个问题......而且因为这也是我第一次拥有“无前缀”命名空间,所以我不确定问题来自这个无前缀命名空间,还是来自视频。

这里有一些示例:

<?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 / 等方面的完美初学者)

【问题讨论】:

    标签: java xml xpath xml-namespaces


    【解决方案1】:

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

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

    【讨论】:

    • 我已经展示了所有三个...不确定我是否理解缺少一个?而且,没有意识到我使用的是 XPath 1.0 ......所以我将看看 Saxon。感谢您的提示!下周二我会给出结果(去WE)。
    • 您的 Java 代码正在为 XMLConstants.DEFAULT_NS_PREFIX 绑定一个命名空间,但这没有任何效果,因为在 XPath 表达式中,无前缀的名称总是指的是没有命名空间中的名称。
    猜你喜欢
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多