将 XML 文件中的键读入 shell 数组
Reading keys from a XML file into a shell array
我正在尝试解析 xml 文件并获取所有标签值和字体值并将它们添加到关联数组。我的问题是数组似乎没有正确分配值
#!/bin/bash
GAME_NAME="."
LOCALIZATION_DIR="$GAME_NAME/assets/data/localization"
INDEX=0
OUTPUT_KEYS=()
# parse english xml for tags and font names first
for str in $(echo "cat //strings/string/@key" | xmllint --shell "$LOCALIZATION_DIR/en.xml")
do
echo "$str"
echo "--"
OUTPUT_KEYS[$index]="$str"
((INDEX++))
done
echo ${OUTPUT_KEYS[0]}
最后一个回显只是回显标签的结尾 >
对数组在 shell 中的工作方式有点困惑,或者是否有更好的方法来解决这个问题。
我的 XML 看起来像这样。
<?xml version="1.0" encoding="UTF-8" ?>
<strings version="5.6051.4-en">
<!--<StarLineUI>-->
<!-- Menu -->
<string key="betProper" value="Bet" fonts="uiAccountTitle" />
<string key="linesProper" value="Lines" fonts="uiAccountTitle" />
<string key="spinsProper" value="Spins" fonts="uiAccountTitle" />
<string key="bet" value="BET" fonts="uiMenuTitle, uiAccountTitle" />
<string key="line" value="LINE" fonts="uiMessage" />
</strings>
我正在尝试构建适用于 GNU bash 版本 3.2.57(1)-release (x86_64-apple-darwin16)
的解决方案
如果您有 bash 4.0 或更新版本:
readarray -t output_keys \
< <(xmlstarlet sel -t -m '//strings/string[@key]' -v @key -n <in.xml)
echo "${output_keys[0]}"
否则:
output_keys=( )
while IFS= read -r line; do
output_keys+=( "$line" )
done < <(xmlstarlet sel -t -m '//strings/string[@key]' -v @key -n <in.xml)
在其中任何一个中,xmlstarlet
的输出只是您要提取的键,如:
betProper
linesProper
spinsProper
bet
line
...这可以像您期望的那样迭代:
for key in "${output_keys[@]}"; do
echo "Found key: $key"
done
如果你没有xmlstarlet
,你可以运行 XSLT等价于上面的命令行;如果您的样式表 print-strings.xslt
包含以下内容:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="//strings/string[@key]">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="@key"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="value-of-template">
<xsl:param name="select"/>
<xsl:value-of select="$select"/>
<xsl:for-each select="exslt:node-set($select)[position()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
...那么你可以 运行:
xsltproc print-strings.xslt in.xml
...获得与 xmlstarlet sel -t -m '//strings/string[@key]' -v @key -n <in.xml
.
相同的输出
我正在尝试解析 xml 文件并获取所有标签值和字体值并将它们添加到关联数组。我的问题是数组似乎没有正确分配值
#!/bin/bash
GAME_NAME="."
LOCALIZATION_DIR="$GAME_NAME/assets/data/localization"
INDEX=0
OUTPUT_KEYS=()
# parse english xml for tags and font names first
for str in $(echo "cat //strings/string/@key" | xmllint --shell "$LOCALIZATION_DIR/en.xml")
do
echo "$str"
echo "--"
OUTPUT_KEYS[$index]="$str"
((INDEX++))
done
echo ${OUTPUT_KEYS[0]}
最后一个回显只是回显标签的结尾 >
对数组在 shell 中的工作方式有点困惑,或者是否有更好的方法来解决这个问题。
我的 XML 看起来像这样。
<?xml version="1.0" encoding="UTF-8" ?>
<strings version="5.6051.4-en">
<!--<StarLineUI>-->
<!-- Menu -->
<string key="betProper" value="Bet" fonts="uiAccountTitle" />
<string key="linesProper" value="Lines" fonts="uiAccountTitle" />
<string key="spinsProper" value="Spins" fonts="uiAccountTitle" />
<string key="bet" value="BET" fonts="uiMenuTitle, uiAccountTitle" />
<string key="line" value="LINE" fonts="uiMessage" />
</strings>
我正在尝试构建适用于 GNU bash 版本 3.2.57(1)-release (x86_64-apple-darwin16)
的解决方案如果您有 bash 4.0 或更新版本:
readarray -t output_keys \
< <(xmlstarlet sel -t -m '//strings/string[@key]' -v @key -n <in.xml)
echo "${output_keys[0]}"
否则:
output_keys=( )
while IFS= read -r line; do
output_keys+=( "$line" )
done < <(xmlstarlet sel -t -m '//strings/string[@key]' -v @key -n <in.xml)
在其中任何一个中,xmlstarlet
的输出只是您要提取的键,如:
betProper
linesProper
spinsProper
bet
line
...这可以像您期望的那样迭代:
for key in "${output_keys[@]}"; do
echo "Found key: $key"
done
如果你没有xmlstarlet
,你可以运行 XSLT等价于上面的命令行;如果您的样式表 print-strings.xslt
包含以下内容:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="//strings/string[@key]">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="@key"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="value-of-template">
<xsl:param name="select"/>
<xsl:value-of select="$select"/>
<xsl:for-each select="exslt:node-set($select)[position()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
...那么你可以 运行:
xsltproc print-strings.xslt in.xml
...获得与 xmlstarlet sel -t -m '//strings/string[@key]' -v @key -n <in.xml
.