代码之家  ›  专栏  ›  技术社区  ›  Ken Bloom

在scala中执行复杂的xpath查询

  •  13
  • Ken Bloom  · 技术社区  · 15 年前

    在scala中,对文档执行下列xpath查询最简单的API是什么?

    //s:Annotation[@type='attitude']/s:Content/s:Parameter[@role='type' and not(text())]
    
    //s:Annotation[s:Content/s:Parameter[@role='id' and not(text())]]/@type
    

    ( s 定义为特定命名空间的昵称)

    我在scala的XML库中找到的唯一文档没有关于执行复杂的真实xpath查询的信息。

    我曾经喜欢 JDOM 为了这个目的(在Java中),但是由于JDOM不支持泛型,所以在斯卡拉中使用它将是痛苦的。(Java中的其他XML库在Java中往往更为痛苦,但我承认我不太了解这个场景。)

    5 回复  |  直到 8 年前
        1
  •  12
  •   Daniel C. Sobral    15 年前
    //s:Annotation[@type='attitude']/s:Content/s:Parameter[@role='type' and not(text())]
    

    嗯,我不明白 s: 符号,在xpath规范中也找不到它。但是,忽略这一点:

    (
      (xml 
        \\ "Annotation" 
        filter (_ \ "@type" contains Text("x"))
      ) 
      \ "Content" 
      \ "Parameter" 
      filter (el => (el \ "@type" contains Text("type")) && el.isInstanceOf[Text])
    )
    

    注意括号的必要性,因为 \ 结束 filter . 我已经将格式改为多行表达式,因为scala等效表达式对于一行来说太冗长了。

    但是,我不能回答有关名称空间的问题。如果可能的话,不知道如何在搜索中使用它们。医生提到 @{uri}attribute 对于带前缀的属性,没有提到任何关于带前缀元素的内容。另外,请注意,您需要传递一个解析为所需命名空间的URI,因为不支持搜索中的文本命名空间。

        2
  •  3
  •   Ken Bloom    15 年前

    我想我会轻轻地拉皮条 XOM . XOM的作者们决定不公开暴露子节点集合等,这是有点羞耻的,但是他们在Java中做的工作比在斯卡拉做的工作要少,也没有什么优势。(这是一个设计良好的图书馆。)

    编辑: 我最后还是对JDOM进行了一些改进,因为XOM不会提前编译XPath查询。因为这次我的大部分工作都是针对XPath的,所以我能够想出一个好的模型来避开大部分的泛型问题。提出合理的方法的仿制药版本不应该太难。 getChildren getAttributes getAdditionalNamespaces 在里面 org.jdom.Element (通过用稍微改变名称的新方法给库拉皮条。)我认为没有解决方法 getContent 我也不确定 getDescendants .

        3
  •  3
  •   Chris    14 年前

    Scales Xml 添加基于字符串的完整XPath评估和内部DSL,为查询提供相当完整的覆盖范围。

        4
  •  1
  •   Ken Bloom    15 年前

    我猜什么时候 scalaxmljaxen 成熟后,我们将能够在scala的内置XML类上可靠地完成这项工作。

        5
  •  0
  •   Nicolas Rinaudo    8 年前

    我建议使用 kantan.xpath :

     import kantan.xpath._
     import kantan.xpath.implicits._
    
     input.evalXPath[List[String]](xp"/annotation[@type='attitude']/content/parameter[@role='type' and not(text())]/@value")
    

    这就产生了:

    res1: kantan.xpath.XPathResult[List[String]] = Success(List(foobar))
    
    推荐文章
    Sembrano  ·  JDOM中的元素列表
    12 年前