使用 groovy 合并 Checkstyle XML 具有相同结构的文档

Merging Checkstyle XML Documents with identical structure using groovy

早上好

我有几个具有相同结构的 Checkstyle XML 报告,我需要合并到一个文档中,文档如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="6.15">
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/communication/EMailMessage.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/communication/EMailSender.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/communication/SMSMessage.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/communication/package-info.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/InputValidation.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/InputValidationALL.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/InputValidationINTEGER.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/InputValidationTEXT.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/MenuNavigationEvent.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/SubscriberForUSSD.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/USSDMenuItem.java">
<error line="327" severity="error" message="Line is longer than 120 characters (found 157)." source="com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck"/>
<error line="327" column="133" severity="error" message="&apos;,&apos; is not followed by whitespace." source="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAfterCheck"/>
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/USSDMenuItemManager.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/USSDResponse.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/ussd/package-info.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/utils/DateUtils.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/utils/DbUtils.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/utils/Enumerators.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/utils/IDNumberValidator.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/utils/SimpleHTTP.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/utils/TextParser.java">
</file>
<file name="/media/sf_Google_Drive/Development/av_microservice/av_microservice/av_microservice_commons/src/main/java/za/co/av/ms_commons/utils/package-info.java">
</file>
</checkstyle>

现在我尝试使用以下代码进行合并

def list = []        
//create new XML file
File newXMLfile= new File("${rootProject.projectDir}/reports/checkStyleCombined.xml" ) 
new StreamingMarkupBuilder().bind {
    mkp.xmlDeclaration([version:'1.0', encoding:'UTF-8', standalone:'no'])
    checkstyle {
        //get list of all checkstyle reports
        def dir = new File("${rootProject.projectDir}/reports/checkstyle")
        dir.eachFileRecurse (FileType.FILES) { file -> 
            list << file
        }
        //itterate though the list
        list.each {
            //parse xml file
            def gPathResult = new XmlSlurper().parse(it)   
            //find all "file" nodes in xml file
            gPathResult.file.each{
                TEST(XmlUtil.serialize(it)) 
                out << it
            }
        }
    }
}.writeTo(newXMLfile.newWriter("UTF-8"))

我遇到的问题是双重的,首先似乎我不能使用 XmlUtil.serialize 方法来编写我的节点,因为它在每一行上放置了一个 XML 声明,格式如下所示。

<TEST>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;file name="XXXXXX"/&gt;

其次,您会在 XML 文件中注意到有一个名为文件的元素。我不能在闭包中使用名称 file 因为 file 是一个保留字所以我使用 "TEST" 但这显然是错误的。所以我的问题很简单,有没有人知道如何以更简单的方式做到这一点。

所以看来我使用的方法并不理想所以我所做的是使用 XML 文档之一作为根文档并将其他文档合并到其中

def list = []    
    //This is for the checkstyle report!!!!!!
    //create new XML file
    File newXMLfile= new File("${rootProject.projectDir}/reports/checkStyleCombined.xml" ) 

    //get list of all checkstyle reports
    def dir = new File("${rootProject.projectDir}/reports/checkstyle")
    dir.eachFileRecurse (FileType.FILES) { file -> 
        list << file
    }
    //set the root xml document to the first document is the list
    def root = new XmlSlurper().parse(list.first())  
    //itterate through the list
    list.each {
        if(it != list.first()) 
        {
            //parse xml file
            def gPathResult = new XmlSlurper().parse(it)   
            //find all file nodes in xml file
            gPathResult.file.each{
                //append node to root node
                root.appendNode(it)
            }
        }
    }
    //write the node to file
    newXMLfile.withWriter { outWriter ->
        XmlUtil.serialize( new StreamingMarkupBuilder().bind{ mkp.yield root }, outWriter )
    }

我希望有一天这对某人有所帮助,因为我花了很长时间才弄明白。