“选择 - 转换”XML转换语言?

时间:2013-04-12 13:31:00

标签: scripting xslt

我想将XML文档转换编写为一次性命令和独立脚本,就像我使用Unix工具一样,例如grepsedawk等等,操纵文本文件。脚本必须可以在Linux和Windows之间移植(使用Cygwin就可以了)。

如果已定期执行此操作,您使用的解决方案是什么?你能推荐一下吗?

(有些背景:

现在,我想从一组XML文档中删除某种元素。 我经常需要做这种系统的XML文档重写; 有时,在运行中(在命令行上,我使用了很多); 更常见的是,我想构建更复杂的转换,将它们保存到文件中,然后从文件中执行它们。

所以我想要一种可以在命令行上使用的XML转换脚本语言。 类似于sedawk的XML文档:它的命令将指定一个选择器,用于选择输入文档中的节点,以及指定在每个选定节点上如何处理文档的操作。

通常,我会用XML::LibXML编写一个Perl脚本。 这有效,但它真的不符合要求:

  • 语法:代码太冗长,无法在命令行上使用
  • 语义:没有给出“选择和转换”模式,我必须将此行为明确地编写到我的代码中,因此读者不必理解这就是真正发生的事情
  • 语法/语义:阅读或编写此代码需要语言通用流利

使用任何其他通用编程语言也是如此。

嗯,这就是XSLT的发明,对吗?

也许; I can use XSLT,但它确实有同样的缺点。

更好的匹配是xmlstarlet:它实际上就像sed,因为它支持我想要的类型的短而神秘的命令。但是,就像使用sed一样,由这些命令组成的较大程序很难理解。

另一个想法是使用jQuery DOM manipulation

  • 比XPath更强大的选择器
  • 优雅紧凑的方式结合选择和操作
  • 使用任意JavaScript函数的内置可扩展性(但在简单情况下不需要很多JavaScript知识)

很好,但是我需要一个允许我将这些表达式用作独立脚本的实用程序:

jqmanip --html '$(a:parent).detach()' foo.html > bar.html
jqmanip convert-tables-to-divs.jqm foo.html > bar.html

这就是我正在寻找的那种实用工具。)

1 个答案:

答案 0 :(得分:0)

现在我正在使用/bin/shxmlstarlet的组合,e..g。

#!/bin/sh
#
# csproj2csproj - clean up VS 2010/2012 C# project files in various ways
#
# $Id$

dft='//*[local-name()="PropertyGroup" and not(@Condition)]'
dbg='//*[local-name()="PropertyGroup" and contains(*/@Condition,"Debug")]'
rel='//*[local-name()="PropertyGroup" and contains(*/@Condition,"Release")]'

RemoveTree()
{
  xmlstarlet ed -d "$1"
}

AppendAsLastChild()
{
  xmlstarlet ed -i "$1"'/*[last()]' -t elem -n "$2" -v "$3"
}

sed 's/encoding="utf-8"/encoding="Windows-1252"/' "$@" |
RemoveTree '//*[@Include="My Project\"]' |
RemoveTree '//*[not(@*|*) and not(normalize-space(.))]' |
RemoveTree '//*[local-name()="LangVersion"]' |
RemoveTree '//*[local-name()="CheckForOverFlowUnderFlow"]' |
RemoveTree '//*[local-name()="DocumentationFile"]' |
AppendAsLastChild "$dft" LangVersion ISO-2 |
AppendAsLastChild "$dbg" CheckForOverflowUnderflow true |
AppendAsLastChild "$rel" CheckForOverflowUnderflow false |
AppendAsLastChild "$rel" DocumentationFile 'bin\Release\vsdocs.xml'