1

我是 awk 的新手,需要一个简单的 awk 脚本来帮助去除所有字符度量并连接属性以将 XML 压缩很多。

输入

<?xml version="1.0"?>
<document>
    <page>
        <block bbox="270 163.717 363.262 224.155">
            <line bbox="270 163.717 274.453 182.669">
                <span bbox="270 163.717 274.453 182.669" font="Helvetica-Bold" size="16.02">
                    <char bbox="270 200.519 284.425 224.155" c="f"/>
                    <char bbox="284.43 200.519 291.082 224.155" c="o"/>
                    <char bbox="291.087 200.519 297.74 224.155" c="o"/>
                </span>
            </line>
            <line bbox="270 200.519 363.262 224.155">
                <span bbox="270 200.519 363.262 224.155" font="Helvetica-Bold" size="19.98">
                    <char bbox="270 200.519 284.425 224.155" c="b"/>
                    <char bbox="284.43 200.519 291.082 224.155" c="a"/>
                    <char bbox="291.087 200.519 297.74 224.155" c="r"/>
                </span>
            </line>
        </block>
    </page>
</document>

期望的输出

<?xml version="1.0"?>
<document>
    <page>
        <block bbox="270 163.717 363.262 224.155">
            <line bbox="270 163.717 274.453 182.669">
                <span bbox="270 163.717 274.453 182.669" font="Helvetica-Bold" size="16.02">foo</span>
            </line>
            <line bbox="270 200.519 363.262 224.155">
                <span bbox="270 200.519 363.262 224.155" font="Helvetica-Bold" size="19.98">bar</span>
            </line>
        </block>
    </page>
</document>

谢谢!

4

3 回答 3

1

尝试类似的东西

awk '{if (index($0, "<char") == 0) print $0}' xmlfile

编辑:试试这个脚本:

gawk '{ if (index($0, "<char") > 0) {mat = gensub(/.*c=\"(.*)\".*/, "\\1", "g"); 
                                     tmp = tmp mat;} 
        else if (index($0, "</span>") > 0)
              { print gensub(/(.*)<\/span>/, "\\1", "g") "  " tmp "\n" $0;
                tmp = "";} 
        else print $0 }' xmlfile

输出:

<?xml version="1.0"?>
<document>
    <page>
        <block bbox="270 163.717 363.262 224.155">
            <line bbox="270 163.717 274.453 182.669">
                <span bbox="270 163.717 274.453 182.669" font="Helvetica-Bold" size="16.02">
                  foo
                </span>
            </line>
            <line bbox="270 200.519 363.262 224.155">
                <span bbox="270 200.519 363.262 224.155" font="Helvetica-Bold" size="19.98">
                  bar
                </span>
            </line>
        </block>
    </page>
</document>
于 2012-05-16T18:19:52.430 回答
1

不建议使用标准的 unix shell 实用程序进行 XML 解析。它需要一个适当的 XML 解析器来做到这一点。

使用 awk 以下命令可以获得输出(假设c=属性始终位于<char>XML 标记中的第二个位置:

awk 'BEGIN {FS="\""} /<char /{tag = tag $4;}
/<\/span>/{print tag; tag="";} !/<char /' file.xml

输出

<?xml version="1.0"?>
<document>
    <page>
        <block bbox="270 163.717 363.262 224.155">
            <line bbox="270 163.717 274.453 182.669">
                <span bbox="270 163.717 274.453 182.669" font="Helvetica-Bold" size="16.02">
foo
                </span>
            </line>
            <line bbox="270 200.519 363.262 224.155">
                <span bbox="270 200.519 363.262 224.155" font="Helvetica-Bold" size="19.98">
bar
                </span>
            </line>
        </block>
    </page>
</document>
于 2012-05-16T18:35:59.443 回答
1

显然,您正在使用 awk,尽管您知道 XML 应该由适当的工具处理。无论如何,必须提到这确实是XSLT的情况。

使用Saxon 6(或更高版本),这样的命令

java -jar saxon.jar input.xml stylesheet.xslt

通过这样的样式表产生所需的结果:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="span">
    <span>
      <xsl:copy-of select="@*"/>
      <xsl:for-each select="char/@c">
        <xsl:value-of select="."/>
      </xsl:for-each>
    </span>
  </xsl:template>
</xsl:stylesheet>
于 2012-05-16T20:20:25.267 回答