0

我在解析具有无前缀名称空间和带有前缀('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>...

这是我使用的代码,下面是我在这里找到的示例:

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

4

1 回答 1

0

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

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

于 2013-08-08T11:41:07.083 回答