XMLStarlet不选择任何内容 [英] XMLStarlet does not select anything
问题描述
我有一个典型的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屋!