在<project> <groupid> .. </groupid>和<project> <parent> <groupid> .. </groupid> </parent> </project> </project>中打印文本

时间:2013-04-18 19:12:01

标签: xpath command-line xquery xmlstarlet

我需要在目录树的许多pom.xml中列出这两个元素中的文本。这些文件也可能包含其他地方的元素,我只是在寻找这两个的内容。

理想情况下,我正在寻找以<file-name>:<line-no>:<path>:<text>格式输出的工具,例如

parent/pom.xml:12:/project/groupId:com.acme.project
features/persist/pom.xml:14:/project/parent/groupId:com.acme.project
features/persist/pom.xml:32:/project/groupId:com.acme.project.persist

对于以下输入文件:

**parent/pom/xml**
<project>
 ...
  <groupId>
  com.acme.project <!--LINE 12 --> 
  </groupId>
...
</project>

**feature/persist/pom.xml**
<project>
  <parent>
    <groupId>
    com.acme.project <!--LINE 14 --> 
    </groupId>
  </parent>
  ...
  <groupId>
  com.acme.project
  </groupId>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>
        a.b.c.d <!-- this is not listed in output -->
        </groupId>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

请注意,不包括其他路径,例如dependencyManagement/dependencies/dependency/groupId

在这里搜索我遇到了xmllint --xpath但我对xpath的了解不足以自己解决这个问题。

2 个答案:

答案 0 :(得分:0)

尝试不带行号的XPath 2.0兼容查询,它会检查匹配<groupID/>元素的所有查询路径并打印其文档名称,构造(不一定是唯一的)路径并添加元素的内容。

(//project/parent | //project)/groupId/string-join(
  (
    base-uri(),
    string-join(('', .//ancestor-or-self::*/name()), '/'),
    data(.)
  ), ':')

您可以使用BaseX collection运行它(例如我用于测试),其中包含您要查询的所有XML文件。

  1. 运行此命令以创建集合: CREATE DB xmldocs /path/to/xml-files
  2. 使用上面的XPath查询数据库
  3. 运行查询有多种方法,请查看Standalone Mode manual

    该查询还应该在其他XPath 2.0兼容引擎中运行,例如saxon(也支持行号,请参阅上面的评论)。

答案 1 :(得分:0)

我最终使用了xml2的cygwin版本:

xml2 <  pom.xml | grep -e "/project/parent/groupId" -e "/project/groupId"
/project/parent/groupId=...
/project/groupId=....