【问题标题】:Create xml file : Using awk how to create an xml file创建 xml 文件:使用 awk 如何创建 xml 文件
【发布时间】:2018-07-29 17:27:26
【问题描述】:

我已经简化了我的问题。

我有一个包含如下数据的文本文件

package1| class1 | test case1 |  Pass  |  endpoint | ref no  |  
package1| class1 | test case2 |  Pass  |  endpoint | ref no  |  
package2| class2 | test case1 |  Fail  |  endpoint | ref no  | fail reason  
package3| class3 | test case2 |        |           |         |

我想从上面创建一个 xml,而如下所示。 每当 field1 与上一行 field1 不同时的逻辑创建一个 节点并在其下测试用例。如果字段 4 为空,则测试被计为错误。我想在包级别(即 节点)记录测试用例的数量、错误和失败的数量。并记录每个 节点的测试用例、错误和失败数

<?xml version="1.0" encoding="UTF-8"?>
<testsuites errors="1" failures="1" tests="4">
  <testsuite name="package1" errors="0" failures="0" tests="2">
    <Testcase>
       <class>class1</class>
       <name>Testcase1</name>
       <Result>Pass</Result>
       <FailReason></FailReason>
    </testcase>
    <Testcase>
      <class>class2</class>
      <name>Testcase2</name>
      <Result>Pass</Result>
      <FailReason></FailReason>
      </testcase>
 </TestSuite>

 <testsuite name="package2" errors="0" failures="1" tests="1">
  <Testcase>
    <class>class1</class>
    <name>Testcase1</name>
    <Result>Fail</Result>
    <FailReason>FailReason</FailReason>
  </testcase>
 </TestSuite>

 <testsuite name="package3" errors="1" failures="0" tests="1">
  <Testcase>
    <class>class1</class>
    <name>Testcase1</name>
    <Result>Fail</Result>
    <FailReason>Error</FailReason>
  </testcase>
 </TestSuite>
</Testsuites>

`

我正在使用 awk 创建尝试了这么多代码,但都没有成功,我不确定我应该把哪个代码放在这里,我尝试了将近 6 个小时的工作,但无法弄清楚如何去做,现在干了。任何帮助表示赞赏。 任何脚本解决方案都很好,不仅是 awk。

【问题讨论】:

  • 不清楚,能否请您在帖子中向我们展示所有条件的预期输出。
  • @RavinderSingh13 我已经编辑了帖子,请看看是否清楚。感谢您的帮助
  • 你的问题能再简洁一点吗?我敢肯定,当它到来时,答案绝对是微不足道的,但我没有时间试图弄清楚你想要做什么,我怀疑其他人也没有,因为你没有答案,到目前为止 5 小时发布问题后。还要确保对所有示例输入/输出使用与用于代码和一些示例相同的 4 空格缩进,这样它们都清晰易读,我们可以直接复制/粘贴以进行测试。
  • @EdMorton 我已经编辑并明确了问题。
  • 您还应该包括您迄今为止尝试过的内容,并确保您发布的预期输出可以从您的示例输入中生成(在您的情况下,idk 输出中的“错误”是什么,但我怀疑您没有不需要它来学习如何解决您的问题,并且您的输出中的大写/小写与您的输入不匹配,而且“错误”不知从何而来,作为 FailReason 出现)。见How to Ask。

标签: xml awk junit


【解决方案1】:

请注意,这不是您问题的完整答案。我不愿意一次性将整个答案作为一个完整的程序分享:评论的代码太长了。

请回到我身边,告诉我到目前为止您是否遵循代码,如果被问到,我将通过编辑我的答案来添加解释。

首先:我先验地删除了原始输入文件中的所有空格。现在看起来像这样:

package1|class1|test case1|Pass|endpoint|ref no|  
package1|class1|test case2|Pass|endpoint|ref no|  
package2|class2|test case1|Fail|endpoint|ref no|fail reason  
package3|class3|test case2|    |        |      |

然后,我将字段分隔符设置为管道并继续进行一些处理。正如许多人已经指出的那样,您的输入文件不一致,并且您的 xml 不兼容。我愿意将所有实际实施留给您(根据 SO 指南,以便您展示自己的努力)

尝试这样的事情:创建一个脚本(您将调用它为awk -f script.awk textfilewithdata.txt)并使其听起来像:

BEGIN {
    FS = "|"
    numberOfPackages = 0
    fails = "fails"
    testcases = "testcases"
}

{
    allTests++
    if ($1 != currPackage) {
        currPackage = $1
        numberOfPackages++
        if (!(currPackage in packages)) {
            # creates it
            packages[currPackage][testcases] = 0    # stores errors, failures and test
            packages[currPackage][fails] = 0
            }
        packages[currPackage][testcases]++
        if ($4 == "Fail" ) {packages[currPackage][fails]++;allFail++}
    } else {
        packages[currPackage][testcases]++
        if ($4 == "Fail" ) {packages[currPackage][fails]++;allFail++}
    }
}

END {
    print "<?xml version="1.0" encoding="UTF-8"?>"
    print "<testsuites failures=\""allFail"\" tests=\""allTests"\">"
    for (j in packages) {
        print "\t<testsuite name=\""j"\"  failures=\""packages[j][fails]"\" tests=\""packages[j][testcases]"\">"
        for (k in packages[j]) {
            print "\t\t<Testcase>"
            print "\t\t\t<class>"
            print "\t\t<\\Testcase>"
        }
        print "\t<\\testsuite>"
    }
}

再次,用 cmets 来找我,我会尝试对上面的代码进行解释。

输出如下所示(gawk 4.2,Windows 10)

<?xml version=1 encoding=-8?>
<testsuites failures="1" tests="4">
        <testsuite name="package1"  failures="0" tests="2">
                <Testcase>
                        <class>
                <\Testcase>
                <Testcase>
                        <class>
                <\Testcase>
        <\testsuite>
        <testsuite name="package2"  failures="1" tests="1">
                <Testcase>
                        <class>
                <\Testcase>
                <Testcase>
                        <class>
                <\Testcase>
        <\testsuite>
        <testsuite name="package3"  failures="0" tests="1">
                <Testcase>
                        <class>
                <\Testcase>
                <Testcase>
                        <class>
                <\Testcase>
        <\testsuite>

【讨论】:

  • 感谢您的回复。看起来我正在朝着正确的方向前进。你能解释一下 if (!(currPackage in package)) 这个数组包来自哪里
  • 哎呀,对不起。数组package 是一个错字。应该是packages。另外,请注意,您可以并且应该使用此架构创建有效的 xml。
  • 请参阅帖子中的内容,我已根据您的建议取得了进展。在我的终端中,我无法使用 a[1][1] 数组,因为您的建议可能是版本差异。但我已将其用作 [1,1,] 类型。
  • 感谢您的路线图帮助。我会为您的回答投票
  • @AbrarAhamed,如果它为您的问题提供了解决方案,请考虑接受答案。
【解决方案2】:

这是生成 junit 测试报告类型 xml 的最终解决方案。几乎两天的努力寻找答案,但很好学到了很多关于 awk 的知识:)

输入是

012_project_y2013 | 01_12.1_new_prodcodes | tc06_s2m_mc_0200_MBT.utt |  Pass  |  MIG_MSI_EP1 MDS_S2A_EP1 |
012_project_y2013 | 01_12.1_new_prodcodes | tc07_s2m_mc_0200_MCW.utt |  Fail  |                          |
012_project_y2013 | 01_12.1_new_prodcodes | tc08_s2m_mc_0200_MCW.utt |  |  |
012_project_y2014 | 01_12.1_new_prodcodes | tc09_s2m_mc_0200_MCW.utt |  |  |

~

BEGIN {
    FS = "|"
}NF==0 {next}
NF>=1{
        allTests +=1;
    if ($1 != package) {
        package = $1;
        class = $2;
        testname = $3;
        testresult = $4;
        endpoint = $5;
        rrn = $6;
        failreason=$7
        numberOfPackages +=1;

        if(!(package in currPackage)){

                if(length(prepkg)!=0){
                testsuite[prepkg,tests,fails,errors];}
                prepkg = package;
                tests=0;
                fails=0;
                errors=0;
                test_result[package,"fail"] = 0;
                test_result[package,"error"] =0;
                test_result[package,"testcase"]=0;

                testcount =0;
            }

}

#       testcase +=1;

        if ($4~/Fail/) {test_result[package,"fail"]  +=1;fails +=1;allFail++}

        if ($4~/^[ ]*$/) {$4="Fail";test_result[package,"error"] +=1; errors +=1;allErrors++}

        if($7~/^[ ]*$/ || $7 == ""){failreason = "error";}

        if($7~/^[ ]*$/ || $7 == ""){failreason = "error";}

        tests +=1;
        currPackage[package,$2,$3,$4,failreason];
        test_result[package,"testcase"]++;

}
END {

                testsuite[package,tests,fails,errors];
    print "<?xml version="1.0" encoding="UTF-8"?>"

    print "<testsuites errors=\""allErrors"\" failures=\""allFail"\" tests=\""allTests"\">"
                for (k in testsuite)
                {
                        split(k,tno,SUBSEP);
                        pname = tno[1];
                        testcnt = tno[2];
                        failcnt = tno[3];
                        errcnt = tno[4];
                        print "\t<testsuite errors=\42"errcnt"\42"" " "failures=\42"failcnt"\42"" " "hostname=\42localhost\42  id=\"0\42  name=\42"pname"\42"" ""package=\42"pname"\42"" " "tests=\42"testcnt"\42"" " "timestamp=\42"date"\42"">";

                        for (y in currPackage)
                        {
                                split(y,sep,SUBSEP);
                                if (pname == sep[1]){
                                print "\t\t<testcase classname=\42"sep[2]"\42"" " "name=\42"sep[3]"\42"" " "time=\42"10"\42"">"
                                tresult = sep[4];
                                reason = sep[5];
                                        if(tresult~/Fail/)
                                        {
                                                                                                            print "\t\t\t<failure message=\42""Assertion FAILED""\42"" " "type=\42""failure""\42"">"reason"</failure>\n";
                                        }
                                }
                        }
                        print  "\t</testsuite>";
                }
                print "</testsuites>";

        }

输出是

<?xml version=1 encoding=-8?>
<testsuites errors="2" failures="1" tests="4">
        <testsuite errors="1" failures="0" hostname="localhost"  id="0"  name="012_project_y2014 " package="012_project_y2014 " tests="1" timestamp="">
                <testcase classname=" 01_12.1_new_prodcodes " name=" tc09_s2m_mc_0200_MCW.utt " time="10">
                        <failure message="Assertion FAILED" type="failure">error</failure>

        </testsuite>
        <testsuite errors="1" failures="1" hostname="localhost"  id="0"  name="012_project_y2013 " package="012_project_y2013 " tests="3" timestamp="">
                <testcase classname=" 01_12.1_new_prodcodes " name=" tc07_s2m_mc_0200_MCW.utt " time="10">
                        <failure message="Assertion FAILED" type="failure">error</failure>

                <testcase classname=" 01_12.1_new_prodcodes " name=" tc06_s2m_mc_0200_MBT.utt " time="10">
                <testcase classname=" 01_12.1_new_prodcodes " name=" tc08_s2m_mc_0200_MCW.utt " time="10">
                        <failure message="Assertion FAILED" type="failure">error</failure>

        </testsuite>
</testsuites>

【讨论】:

  • 此处的输出与原始问题中的输出完全不同,但原理相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-31
  • 2011-11-09
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
相关资源
最近更新 更多