我已成功使用以下命令将XML文件转换为文件YAMLxq
是否可以使用以下工具jq, yq,xq来转换YAML或JSON转换回某种XML格式?
这是我的示例文件的示例JSON:
{
"security-settings": {
"@xmlns": "urn:activemq:core",
"security-setting": {
"@match": "#",
"permission": [
{
"@type": "createNonDurableQueue",
"@roles": "admins"
},
{
"@type": "deleteNonDurableQueue",
"@roles": "admins"
},
{
"@type": "manage",
"@roles": "admins"
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
衷心感谢您的任何帮助或建议。
附加信息:
我最初使用的源 XML 如下:
<?xml version="1.0"?>
<security-settings xmlns="urn:activemq:core">
<security-setting match="#">
<permission type="createNonDurableQueue" roles="admins"/>
<permission type="deleteNonDurableQueue" roles="admins"/>
<permission type="createDurableQueue" roles="admins"/>
<permission type="deleteDurableQueue" roles="admins"/>
<permission type="createAddress" roles="admins"/>
<permission type="deleteAddress" roles="admins"/>
<permission type="consume" roles="admins"/>
<permission type="browse" roles="admins"/>
<permission type="send" roles="admins"/>
<permission type="manage" roles="admins"/>
</security-setting>
</security-settings>
Run Code Online (Sandbox Code Playgroud)
使用命令从XML到 的正向转换生成输出:JSONxq -yY < security-settings.xmlJSON
{
"security-settings": {
"@xmlns": "urn:activemq:core",
"security-setting": {
"@match": "#",
"permission": [
{
"@type": "createNonDurableQueue",
"@roles": "admins"
},
{
"@type": "deleteNonDurableQueue",
"@roles": "admins"
},
{
"@type": "createDurableQueue",
"@roles": "admins"
},
{
"@type": "deleteDurableQueue",
"@roles": "admins"
},
{
"@type": "createAddress",
"@roles": "admins"
},
{
"@type": "deleteAddress",
"@roles": "admins"
},
{
"@type": "consume",
"@roles": "admins"
},
{
"@type": "browse",
"@roles": "admins"
},
{
"@type": "send",
"@roles": "admins"
},
{
"@type": "manage",
"@roles": "admins"
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过运行yq -o=xml -P json_file从JSON到 的向后转换建议的本机转换XML不会生成与XML前面所示的源相同的结果。
<security-settings>
<@xmlns>urn:activemq:core</@xmlns>
<security-setting>
<@match>#</@match>
<permission>
<@type>createNonDurableQueue</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>deleteNonDurableQueue</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>createDurableQueue</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>deleteDurableQueue</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>createAddress</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>deleteAddress</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>consume</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>browse</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>send</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>manage</@type>
<@roles>admins</@roles>
</permission>
</security-setting>
</security-settings>
Run Code Online (Sandbox Code Playgroud)
我在 Fedora 36 虚拟机上运行,这是我在盒子上安装的 yq
yq --version
yq 3.0.2
yq --help
usage: yq [options] <jq filter> [input file...]
yq: Command-line YAML processor - jq wrapper for YAML documents
yq transcodes YAML documents to JSON and passes them to jq.
See https://github.com/kislyuk/yq for more information.
positional arguments:
jq_filter
files
options:
-h, --help show this help message and exit
--yaml-output, --yml-output, -y
Transcode jq JSON output back into YAML and emit it
--yaml-roundtrip, --yml-roundtrip, -Y
Transcode jq JSON output back into YAML and emit it. Preserve YAML tags and styles by representing them as extra items in their enclosing mappings and sequences while in JSON. This option is incompatible with jq filters that do not expect these extra items.
--width WIDTH, -w WIDTH
When using --yaml-output, specify string wrap width
--indentless-lists, --indentless
When using --yaml-output, indent block style lists (sequences) with 0 spaces instead of 2
--in-place, -i Edit files in place (no backup - use caution)
--version show program's version number and exit
jq - commandline JSON processor [version 1.6]
Usage: jq [options] <jq filter> [file...]
jq [options] --args <jq filter> [strings...]
jq [options] --jsonargs <jq filter> [JSON_TEXTS...]
jq is a tool for processing JSON inputs, applying the given filter to
its JSON text inputs and producing the filter's results as JSON on
standard output.
The simplest filter is ., which copies jq's input to its output
unmodified (except for formatting, but note that IEEE754 is used
for number representation internally, with all that that implies).
For more advanced filters see the jq(1) manpage ("man jq")
and/or https://stedolan.github.io/jq
Example:
$ echo '{"foo": 0}' | jq .
{
"foo": 0
}
Some of the options include:
-c compact instead of pretty-printed output;
-n use `null` as the single input value;
-e set the exit status code based on the output;
-s read (slurp) all inputs into an array; apply filter to it;
-r output raw strings, not JSON texts;
-R read raw strings, not JSON texts;
-C colorize JSON;
-M monochrome (don't colorize JSON);
-S sort keys of objects on output;
--tab use tabs for indentation;
--arg a v set variable $a to value <v>;
--argjson a v set variable $a to JSON value <v>;
--slurpfile a f set variable $a to an array of JSON texts read from <f>;
--rawfile a f set variable $a to a string consisting of the contents of <f>;
--args remaining arguments are string arguments, not files;
--jsonargs remaining arguments are JSON arguments, not files;
-- terminates argument processing;
Named arguments are also available as $ARGS.named[], while
positional arguments are available as $ARGS.positional[].
See the manpage for more options.
Run Code Online (Sandbox Code Playgroud)
@池上
这是输出:
回声 <ele attr_name="attr_value">ele_value</ele> | xq
{
"security-settings": {
"@xmlns": "urn:activemq:core",
"security-setting": {
"@match": "#",
"permission": [
{
"@type": "createNonDurableQueue",
"@roles": "admins"
},
{
"@type": "deleteNonDurableQueue",
"@roles": "admins"
},
{
"@type": "createDurableQueue",
"@roles": "admins"
},
{
"@type": "deleteDurableQueue",
"@roles": "admins"
},
{
"@type": "createAddress",
"@roles": "admins"
},
{
"@type": "deleteAddress",
"@roles": "admins"
},
{
"@type": "consume",
"@roles": "admins"
},
{
"@type": "browse",
"@roles": "admins"
},
{
"@type": "send",
"@roles": "admins"
},
{
"@type": "manage",
"@roles": "admins"
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
回声 <ele attr_name="attr_value">ele_value</ele> | xq | ./yq_linux_amd64 -o=xml -P
<security-settings>
<@xmlns>urn:activemq:core</@xmlns>
<security-setting>
<@match>#</@match>
<permission>
<@type>createNonDurableQueue</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>deleteNonDurableQueue</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>createDurableQueue</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>deleteDurableQueue</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>createAddress</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>deleteAddress</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>consume</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>browse</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>send</@type>
<@roles>admins</@roles>
</permission>
<permission>
<@type>manage</@type>
<@roles>admins</@roles>
</permission>
</security-setting>
</security-settings>
Run Code Online (Sandbox Code Playgroud)
jq:
"@" as $attr_prefix |
"#text" as $content_key |
# ">" (only) needs to be escaped if preceded by "]]". We'll do it unconditionally.
# Some whitespace also needs escaping, at least in attribute. Not done here.
{ "&": "&", "<": "<", ">": ">" } as $escapes |
{ "&": "&", "<": "<", "\"": """ } as $attr_escapes |
def text_to_xml: split( "" ) | map( $escapes[.] // . ) | join( "" );
def text_to_xml_attr_val: split( "" ) | map( $attr_escapes[.] // . ) | join( "" );
def node_to_xml:
if type == "string" then
text_to_xml
else
(
if .attrs then
.attrs |
to_entries |
map( " " + .key + "=\"" + ( .value | text_to_xml_attr_val ) + "\"" ) |
join( "" )
else
""
end
) as $attrs |
if .children and ( .children | length ) > 0 then
( .children | map( node_to_xml ) | join( "" ) ) as $children |
"<" + .name + $attrs + ">" + $children + "</" + .name + ">"
else
"<" + .name + $attrs + "/>"
end
end
;
def fix_tree( $name ):
type as $type |
if $type == "array" then
.[] | fix_tree( $name )
elif $type == "object" then
reduce to_entries[] as { key: $k, value: $v } (
{ name: $name, attrs: {}, children: [] };
if $k[0:1] == $attr_prefix then
.attrs[ $k[1:] ] = $v
elif $k == $content_key then
.children += [ $v ]
else
.children += [ $v | fix_tree( $k ) ]
end
)
else
{ name: $name, attrs: {}, children: [ . ] }
end
;
def fix_tree: fix_tree( "" ) | .children[];
fix_tree | node_to_xml
Run Code Online (Sandbox Code Playgroud)
jqplay 上的演示
它是使用调用的
"@" as $attr_prefix |
"#text" as $content_key |
# ">" (only) needs to be escaped if preceded by "]]". We'll do it unconditionally.
# Some whitespace also needs escaping, at least in attribute. Not done here.
{ "&": "&", "<": "<", ">": ">" } as $escapes |
{ "&": "&", "<": "<", "\"": """ } as $attr_escapes |
def text_to_xml: split( "" ) | map( $escapes[.] // . ) | join( "" );
def text_to_xml_attr_val: split( "" ) | map( $attr_escapes[.] // . ) | join( "" );
def node_to_xml:
if type == "string" then
text_to_xml
else
(
if .attrs then
.attrs |
to_entries |
map( " " + .key + "=\"" + ( .value | text_to_xml_attr_val ) + "\"" ) |
join( "" )
else
""
end
) as $attrs |
if .children and ( .children | length ) > 0 then
( .children | map( node_to_xml ) | join( "" ) ) as $children |
"<" + .name + $attrs + ">" + $children + "</" + .name + ">"
else
"<" + .name + $attrs + "/>"
end
end
;
def fix_tree( $name ):
type as $type |
if $type == "array" then
.[] | fix_tree( $name )
elif $type == "object" then
reduce to_entries[] as { key: $k, value: $v } (
{ name: $name, attrs: {}, children: [] };
if $k[0:1] == $attr_prefix then
.attrs[ $k[1:] ] = $v
elif $k == $content_key then
.children += [ $v ]
else
.children += [ $v | fix_tree( $k ) ]
end
)
else
{ name: $name, attrs: {}, children: [ . ] }
end
;
def fix_tree: fix_tree( "" ) | .children[];
fix_tree | node_to_xml
Run Code Online (Sandbox Code Playgroud)
您还可以将程序放入文件中(例如json_to_xml.jq)并使用以下命令:
jq -r 'above progam' file.json >file.xml
Run Code Online (Sandbox Code Playgroud)
我采取了两步走的方法。我首先将输入转换为明确的格式,然后将此结果转换为 XML。这两个步骤可以合并。这是所提供输入的第一次转换的结果:
jq -rf json_to_xml.jq file.json >file.xml
Run Code Online (Sandbox Code Playgroud)
请注意,原始 XML 转换后的格式是有损的。例如,它会丢失具有不同名称的 XML 元素的相对顺序。这意味着上述程序的输出可能与原始 XML 有很大不同。但除非您使用无损的 JSON 模式,否则这是不可避免的。
另一种工具(也称为yq)使用jq类似语法,并且更好地支持 XML 和 JSON 之间的转换。您可以从版本页面下载最新版本。与 kislyuk 不同,yq/xq它实际上并不用于jq处理,因此您可能需要jq稍微调整脚本。
使用 mikefarah's yq,可以使用以下命令重新生成 XML:
./yq_linux_amd64 \
--xml-attribute-prefix @ \
--xml-content-name '#text' \
--input-format yaml \
--output-format xml \
security-settings.yaml
Run Code Online (Sandbox Code Playgroud)
相同的命令也适用于 JSON 输入,因为 JSON 是 YAML 的子集。
| 归档时间: |
|
| 查看次数: |
7196 次 |
| 最近记录: |