我有一个 XML 颜色文件,我想将其转换为 Kotlin 等效文件。给定这个输入文件
颜色.xml
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<!-- Color Scheme -->
<color name="primary">#YYYYYY</color>
<color name="primary_variant">#ZZZZZZ</color>
...
</resources>
这是我正在寻找的输出
颜色.kt
// Color Scheme
val primary = Color(0xFFYYYYYY)
val primaryVariant = Color(0xFFZZZZZZ)
...
我已经编写了一个 Python 脚本来完成此任务,但我对 shell 解决方案的复杂性差异感兴趣,而我对此还不够熟练。
具体来说,我正在寻找的是:
- 评论被映射到 Kotlin 评论
- 保留换行符,不保留缩进
- 变量名从snake_case转换为camelCase
答案1
给定 XML 文档
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<!-- Color Scheme -->
<color name="primary">#YYYYYY</color>
<color name="primary_variant">#ZZZZZZ</color>
<color name="primary_variant">#ZZZZZZ</color>
<color name="primary_variant_old">#ZZZZZZ</color>
<color name="primary_variant_new">#ZZZZZZ</color>
</resources>
在 中file.xml
,您可以使用该xq
实用程序来获取您想要的输出,如下所示:
xq -r '.resources.color[] |
"val " +
( ."@name" | gsub("_(?<a>.)"; .a | ascii_upcase) ) +
" = Color(" +
( ."#text" | sub("#"; "0xFF") ) +
")"' file.xml
或者,可能更容易阅读,
xq -r '.resources.color[] |
[ ( ."@name" | gsub("_(?<a>.)"; .a | ascii_upcase) ),
( ."#text" | sub("#"; "0xFF") ) ] |
"val " + .[0] + " = Color(" + .[1] + ")"' file.xml
这会挑选出每个颜色条目,并将修改后的属性值name
和color
节点值插入到随后输出的字符串中。
通过将每个(其中是任何字符)转换为(大写),该name
属性将转换为驼峰式大小写。然后节点值被替换为。_x
x
X
x
color
#
0xFF
这将输出
val primary = Color(0xFFYYYYYY)
val primaryVariant = Color(0xFFZZZZZZ)
val primaryVariant = Color(0xFFZZZZZZ)
val primaryVariantOld = Color(0xFFZZZZZZ)
val primaryVariantNew = Color(0xFFZZZZZZ)
该xq
实用程序是将 XML 转换为 JSON 的工具。然后,该xq
工具成为众所周知的jq
JSON 解析器的包装器,因此jq
表达式可用于修改或通常使用 XML 文档结构。它是实用程序发行版的一部分yq
(最初是 YAML 解析器包装器jq
),可在以下位置找到:https://kislyuk.github.io/yq/ ( Linux 上yq
可用的实用程序snap
也是 YAML 解析器,但是一个完全不同的工具!)
xq
与大多数其他解析器一样,解析器会丢弃注释。
xq
作为参考,这是将上述 XML 转换为的JSON 文档:
{
"resources": {
"color": [
{
"@name": "primary",
"#text": "#YYYYYY"
},
{
"@name": "primary_variant",
"#text": "#ZZZZZZ"
},
{
"@name": "primary_variant",
"#text": "#ZZZZZZ"
},
{
"@name": "primary_variant_old",
"#text": "#ZZZZZZ"
},
{
"@name": "primary_variant_new",
"#text": "#ZZZZZZ"
}
]
}
}