命令行下Saxon-HE 9.6的换行输出

3
有没有什么方法可以在Saxon-HE 9.6上多个匹配节点的输出中获取换行符分隔的结果?
我使用名为“ saxon-lint”的包装器:
#!/bin/bash

java -cp /path/to/saxon9he.jar net.sf.saxon.Query -s:"$2" -qs:"$1" !method=text

示例:

file.xml

(文件名)
<house_pet_hazards>
  <hazard type="cleanup">
    <name>hairballs</name>
    <guilty_party species="cat">Dilly</guilty_party>
    <guilty_party species="cat">Nameless</guilty_party>
    <guilty_party species="cat">Katie</guilty_party>
  </hazard>
</house_pet_hazards>

命令行:

$ saxon-lint '/house_pet_hazards/hazard/guilty_party' file.xml

输出:

DillyNamelessKatie

预期输出:

Dilly
Nameless
Katie

编辑

我通过搜索谷歌发现了一个半工作的解决方案,由迈克尔·凯提出,所以我编写了这个包装器:

#!/bin/bash

xpath="$1"
[[ -s $2 ]] && file="$(readlink -f "$2")" || file=/dev/stdin

java -cp saxon9he.jar net.sf.saxon.Query -qs:"for \$x in doc('file://$file')$xpath
return (data(\$x),text{'&#10;'})" !method=text

输出:

$ saxon-lint "/house_pet_hazards/hazard/guilty_party" /tmp/file.xml
Dilly
Nameless
Katie

但我发现的问题是,当我使用路径

时,会导致意外的结果。
house_pet_hazards/hazard/guilty_party

我收到一个错误信息。
Error on line 1 column 37 
  XPST0003 XQuery syntax error near #...p/file.xml')house_pet_hazards/#:
    expected "return", found name "house_pet_hazards"
Static error(s) in query

或者

./house_pet_hazards/hazard/guilty_party

我收到错误提示:

Error on line 1 column 37 
  XPST0003 XQuery syntax error near #... doc('file:///tmp/file.xml')./#:
    expected "return", found "."
Static error(s) in query

包装器



(注:该内容为标题和分割线,无需翻译)
3个回答

4
当然可以,只需将查询字符串更改为以下内容:
-qs:"string-join(/house_pet_hazards/hazard/guilty_party,'&#xA;')"

你也可以将路径缩短为//guilty_party

Cygwin中的示例Bash脚本:

[/cygdrive/c/apps/SaxonHE9-6-0-3J]
==> cat saxon-lint.bsh
#!/bin/bash.exe

java -cp saxon9he.jar net.sf.saxon.Query -s:$2 -qs:"string-join($1,'&#xA;')" !method=text

[/cygdrive/c/apps/SaxonHE9-6-0-3J]
==> ./saxon-lint.bsh //guilty_party so.xml
Dilly
Nameless
Katie

1
是的,你在查询字符串中使用了count()函数,它返回一个整数。这不能作为string-join()函数的第一个参数。也许你应该将string-join()函数移出bash,在命令行上使用它。在bash中,只需将查询字符串设置为-qs:“$1”。 - Daniel Haley

2
您的查询选择了三个元素节点;文本输出方法的效果是构造一个包含这三个元素的文档节点,然后输出文档节点的字符串值,该值是三个元素字符串值的连接。
原则上,您可以通过将item-separator序列化属性设置为换行符来解决此问题。不幸的是,我找不到任何在命令行上实现此目的的方法,因为换行符会终止命令。也许!item-separator="\n"在某些shell中可以正常工作,但当我尝试时,您将得到一个"\n"字面量作为项目分隔符。
因此,我认为您必须更改查询以显式插入分隔符,使用string-join()函数。

谢谢Michael Kay。在Mac OS X上使用!key=value是否存在已知问题?在Cygwin和Linux上测试OK。我在github上发布了我的包装器:https://github.com/sputnick-dev/saxon-lint/blob/master/saxon-lint - Gilles Quénot
1
在某些类Unix的shell中(我不确定是哪些),"!"需要转义为"!"。 - Michael Kay
我尝试过这个,但据我所知它更像是交互式 shell(如 bash)中的一种行为。无论如何,我的 Mac Os X 是2006年的版本,所以我必须在新的 Os X 上进行测试。就我使用 [tag:bash] 而言,使用 $'\n' 作为分隔符似乎是可移植的,并且在 Linux/Cygwin 上运行良好。 - Gilles Quénot

0
在Bash中,您可以将此作为序列化参数添加:
 $'!item-separator=\n'

这里使用了bash的$''语法,它可以启用一些转义字符,例如\n

请注意,它不会在最后一项后打印换行符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接