2

我有一个包含某些语言文本的 XML 文件。我想只用一种语言提取文本并将它们存储在一个单独的文件中。我怎样才能做到这一点?这是我的文件的一些开头行:

<?xml version="1.0" encoding="UTF-8"?>
<tmx version="1.4b">
  <header creationtool="ORESAligner" creationtoolversion="1.0" datatype="plaintext" segtype="paragraph" adminlang="en-us" srclang="EN" o-tmf="ORES"/>
  <body>
    <tu tuid="55_100:6">
      <prop type="session">55</prop>
      <prop type="committee">3</prop>
      <tuv xml:lang="EN">
        <seg>RESOLUTION 55/100</seg>
      </tuv>
      <tuv xml:lang="AR">
        <seg>القرار 55/100</seg>
      </tuv>
      <tuv xml:lang="ZH">
        <seg>第55/100号决议&lt;/seg>
      </tuv>
      <tuv xml:lang="FR">
        <seg>RÉSOLUTION 55/100</seg>
      </tuv>
      <tuv xml:lang="RU">
        <seg>РЕЗОЛЮЦИЯ 55/100</seg>
      </tuv>
      <tuv xml:lang="ES">
        <seg>RESOLUCIÓN 55/100</seg>
      </tuv>
    </tu>
  </body>
</tmx>

现在说我只想要英文文本。所需的输出应该是:

RESOLUTION 55/100

我应该如何使用这个脚本?我是处理 XML 文件的新手,不知道如何使用这个 XPath 表达式。据我所知,xmlstarlet 能够修改 XML 文件。但我不知道怎么...?

4

4 回答 4

3

用 XmlStarlet 提取英文节点

您可以使用xmlstarlet 使用XPath查询的 XML,并仅返回具有英语属性的节点。例如:

$ xmlstarlet sel -t -v "//tuv[@xml:lang='EN']/seg/text()" /tmp/foo
RESOLUTION 55/100

将节点值存储在具有语言扩展名的文件中

如果您想将这些值存储在某个基于语言的文件中,那么您可以将找到的每个节点的值转储到具有基于语言的扩展名的文件中(例如,“EN”表示英语)。

# Don't overwrite LANG; use some other variable.
language='EN'

xmlstarlet sel \
    --noblanks \
    --text \
    --template \
    --match "//tuv[@xml:lang='${language}']" \
    --value-of seg \
    -n \
    /tmp/foo > "/tmp/foo.$language"

在此示例中,所有匹配节点的内容将写入/tmp/foo.EN以进行进一步处理。您当然可以调整 shell 重定向以适应任何其他要求。

于 2012-07-23T00:35:26.033 回答
1

如果 xml 文件格式正确,可以使用简单的 sed 命令:

sed -n '/xml:lang="EN"/ {
N
s_.*<seg>\([^<]*\)</seg>_\1_p
}
' input_file

描述:

sed -n '/xml:lang="EN"/ {           # 1) exec sed with no print flag, find a line
                                    # matching xml:lang="EN"
N                                   # 2) read the next line
s_.*<seg>\([^<]*\)</seg>_\1_p       # 3) replace everything until </seg> with 
                                    # the text between <seg> and </seg> and print
}
' input_file

如果要保留seg标签,可以更改第三步:

sed -n '/xml:lang="EN"/ {
N
s_.*\(<seg>[^<]*</seg>\)_\1_p
}
' input_file
于 2012-07-22T11:16:56.090 回答
1

以下 XPath 表达式提取您要查找的信息:

/tmx/body/tu/tuv[@xml:lang='EN']/seg

有许多工具允许您使用 XPath 表达式处理 XML 文件。如果您从命令行工作,您可以查看xmlsh.

很难说出需求的上下文,但我想随着它超出此处给出的简单案例,您会想要查看 XSLT 和/或 XQuery。

于 2012-07-22T11:49:23.640 回答
0

您可以像这样使用命令行工具xml_grep

xml_grep --cond "tu/tuv[@xml:lang='EN']/seg" --text_only file.tmx

to 的参数--cond是一个类似 XPath 的表达式。它的语法类似于xstarletetc. 所期望的,但并不完全相同。

于 2014-03-29T18:40:43.990 回答