需要一些xml节点concat的awk脚本

时间:2012-05-16 18:11:28

标签: xml awk

我是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>

谢谢!

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:1)

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

使用awk follow命令获取输出(假设c=属性始终位于<char> XML标记中的第2个位置:

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>

答案 2 :(得分: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>