我想将XML文档转换编写为一次性命令和独立脚本,就像我使用Unix工具一样,例如grep
,sed
,awk
等等,操纵文本文件。脚本必须可以在Linux和Windows之间移植(使用Cygwin就可以了)。
如果已定期执行此操作,您使用的解决方案是什么?你能推荐一下吗?
(有些背景:
现在,我想从一组XML文档中删除某种元素。 我经常需要做这种系统的XML文档重写; 有时,在运行中(在命令行上,我使用了很多); 更常见的是,我想构建更复杂的转换,将它们保存到文件中,然后从文件中执行它们。
所以我想要一种可以在命令行上使用的XML转换脚本语言。
类似于sed
或awk
的XML文档:它的命令将指定一个选择器,用于选择输入文档中的节点,以及指定在每个选定节点上如何处理文档的操作。
通常,我会用XML::LibXML编写一个Perl脚本。 这有效,但它真的不符合要求:
使用任何其他通用编程语言也是如此。
嗯,这就是XSLT的发明,对吗?
也许; I can use XSLT,但它确实有同样的缺点。
更好的匹配是xmlstarlet:它实际上就像sed
,因为它支持我想要的类型的短而神秘的命令。但是,就像使用sed一样,由这些命令组成的较大程序很难理解。
另一个想法是使用jQuery DOM manipulation:
很好,但是我需要一个允许我将这些表达式用作独立脚本的实用程序:
jqmanip --html '$(a:parent).detach()' foo.html > bar.html
jqmanip convert-tables-to-divs.jqm foo.html > bar.html
这就是我正在寻找的那种实用工具。)
答案 0 :(得分:0)
现在我正在使用/bin/sh
和xmlstarlet
的组合,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'