XMLStarlet不选择任何内容 [英] XMLStarlet does not select anything

查看:139
本文介绍了XMLStarlet不选择任何内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个典型的pom.xml,想要打印由冒号分隔的groupId,artifactId和版本.我认为 XMLStarlet 是正确的工具.我尝试了几种方法,但总会出现空白.

I have a typical pom.xml, and want to print the groupId, artifactId and version, separated by colon. I think that XMLStarlet is the right tool for that. I tried several ways, but I always get an empty line.

xml sel -t -m project -v groupId -o : -v artifactId -o : -v version pom.xml

预期输出:

org.something.apps:app-acct:5.4

实际输出:空行

即使我仅尝试打印groupId,我也一无所获:

Even if I try to print just the groupId I get nothing:

xml sel -t -v project/groupId pom.xml

我确信该工具可以看到这些元素,因为我可以毫无问题地列出它们:

I am sure that the tool sees the elements because I can list them without problem:

xml el pom.xml

(正确)打印以下内容:

prints the following (correctly):

project
project/modelVersion
project/parent
project/parent/groupId
project/parent/artifactId
project/parent/version
project/groupId
project/artifactId
project/version
project/packaging

怎么了?

这是pom.xml的简化版本:

Here is the cut-down version of pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                        http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.something</groupId>
        <artifactId>base</artifactId>
        <version>1.16</version>
    </parent>

    <groupId>org.something.apps</groupId>
    <artifactId>app-acct</artifactId>
    <version>5.4</version>
    <packaging>war</packaging>

</project>

推荐答案

不幸的是,XMLStarlet对默认名称空间非常挑剔.如果文档已声明(xmlns=),则还必须为XMLStarlet声明它,并为元素添加您选择的名称(请参见

Unfortunately, XMLStarlet is very picky about the default namespace. If the document has it declared (xmlns=), you have to declare it for XMLStarlet too, and prefix the elements with the name you have chosen (see here):

xml sel -N my = http://maven.apache.org/POM/4.0.0 -t -m my:project -v my:groupId -o:-v my:artifactId -o:-v my:version pom.xml

xml sel -N my=http://maven.apache.org/POM/4.0.0 -t -m my:project -v my:groupId -o : -v my:artifactId -o : -v my:version pom.xml

运行上面的命令将提供预期的输出:

Running the above command gives the expected output:

org.something.apps:app-acct:5.4

但是,如果文档没有声明默认的名称空间(或者名称空间具有略有不同的URL),则上述命令将不起作用,这是真实的PITA.一个更通用的解决方案是在选择元素之前删除默认的名称空间声明.从XMLStarlet 1.3.1开始,将XML转换为PYX格式并返回将删除名称空间声明:

However, if the document does NOT have the default namespace declared (or the namespace has a slightly different URL), the above command will NOT work, which is a real PITA. A more universal solution is to remove the default namespace declaration before selecting the elements. As of XMLStarlet 1.3.1, converting the XML to PYX format and back removes the namespace declarations:

xml pyx pom.xml | xml p2x | xml sel -t -m project -v groupId -o:-vartifactId -o:-v版本2> nul

xml pyx pom.xml | xml p2x | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version 2>nul

更新(2014-02-12):自XMLStarlet 1.4.2起,PYX<-> XML转换已修复(不会删除名称空间声明),因此上述命令将不起作用(感谢Peter Gluck的小费).请改用以下命令:

UPDATE (2014-02-12): as of XMLStarlet 1.4.2 the PYX <-> XML conversion is fixed (does not remove namespace declarations), so the above command will NOT work (thanks for Peter Gluck for the tip). Use the following command instead:

xml pyx pom.xml | grep -v ^ A | xml p2x | xml sel -t -m project -v groupId -o:-vartifactId -o:-v版本

xml pyx pom.xml | grep -v ^A | xml p2x | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version

注意:上面的grep会删除文档中的所有属性,而不仅仅是命名空间声明.对于这种特定情况(从pom.xml中选择元素值不期望带有非默认名称空间的元素)是可以的,但是对于常规XML,您将仅删除默认的名称空间声明,而不会删除其他内容:

Note: the grep above removes ALL attributes from the document, not just namespace declarations. For this specific case (selecting element values from pom.xml where elements with non-default namespaces are not expected) it is Ok, but for a general XML you would remove just the default namespace declaration(s) and nothing else:

xml pyx pom.xml | grep -v"^ Axmlns" | xml p2x | xml sel -t -m project -v groupId -o:-vartifactId -o:-v版本

xml pyx pom.xml | grep -v "^Axmlns " | xml p2x | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version


注意(已作废):错误重定向(2>nul)对于隐藏关于(现在)未知名称空间xsi的投诉是必需的:


Note (obsolete): the error redirection (2>nul) is necessary to hide the complaint about the (now) unknown namespace xsi:

-:1.28:未定义项目上schemaLocation的命名空间前缀xsi

-:1.28: Namespace prefix xsi for schemaLocation on project is not defined

摆脱投诉的另一种方法是删除schemaLocation属性(实际上,此命令从PYX文档中删除所有属性,而不仅仅是xsi:schemaLocation):

Another way of getting rid of the complaint is to remove the schemaLocation attribute (actually, this command removes all attributes from the PYX document, not just xsi:schemaLocation):

xml pyx pom.xml | grep -v ^ A | xml p2x | xml sel -t -m project -v groupId -o:-vartifactId -o:-v版本

xml pyx pom.xml | grep -v ^A | xml p2x | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version

这篇关于XMLStarlet不选择任何内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆