Groovy - Разбор XML Ответ, Выбор полей, Создание нового файла - PullRequest
0 голосов
/ 30 апреля 2020

Я думаю, что я прочитал каждый Groovy вопрос разбора здесь, но я не могу найти свой точный сценарий, поэтому я обращаюсь за помощью - пожалуйста, будьте добры, я новичок в Groovy и Я действительно откусила больше, чем могу прожевать в этом последнем начинании.

Итак, у меня есть XML Ответ:

<?xml version="1.0" encoding="UTF-8"?>
<worklogs date_from="2020-04-19 00:00:00" date_to="2020-04-25 23:59:59" number_of_worklogs="60" format="xml" diffOnly="false" errorsOnly="false" validOnly="false" addDeletedWorklogs="true" addBillingInfo="false" addIssueSummary="true" addIssueDescription="false" duration_ms="145" headerOnly="false" userName="smm288" addIssueDetails="false" addParentIssue="false" addUserDetails="true" addWorklogDetails="false" billingKey="" issueKey="" projectKey="" addApprovalStatus="true" >
    <worklog>
        <worklog_id></worklog_id>
        <jira_worklog_id></jira_worklog_id>
        <issue_id></issue_id>
        <issue_key></issue_key>
        <hours></hours>
        <work_date></work_date>
        <username></username>
        <staff_id />
        <billing_key></billing_key>
        <billing_attributes></billing_attributes>
        <activity_id></activity_id>
        <activity_name></activity_name>
        <work_description></work_description>
        <parent_key></parent_key>
        <reporter></reporter>
        <external_id />
        <external_tstamp />
        <external_hours></external_hours>
        <external_result />
        <customField_11218></customField_11218>
        <customField_12703></customField_12703>
        <customField_12707></customField_12707>
        <hash_value></hash_value>
        <issue_summary></issue_summary>
        <user_details>
            <full_name></full_name>
            <email></email>
            <user-prop key="auto_approve_timesheet"></user-prop>
            <user-prop key="cris_id"></user-prop>
            <user-prop key="iqn_gl_string"></user-prop>
            <user-prop key="is_contractor"></user-prop>
            <user-prop key="is_employee"></user-prop>
            <user-prop key="it_leadership"></user-prop>
            <user-prop key="primary_role"></user-prop>
            <user-prop key="resource_manager"></user-prop>
            <user-prop key="team"></user-prop>
        </user_details>
        <approval_status></approval_status>
        <timesheet_approval>
            <status></status>
            <status_date></status_date>
            <reviewer></reviewer>
            <actor></actor>
            <comment></comment>
        </timesheet_approval>
    </worklog>
    ....
    ....
</worklogs>

И я получаю этот XML Ответ от вызова API, чтобы ответ удерживался внутри объекта. ПРИМЕЧАНИЕ: Образец XML выше от Почтальона.

Я пытаюсь сделать следующее: 1. Из этого ответа извлекать только определенные значения из всех узлов. 2. Запишите собранные значения в файл. json.

Я создал карту, но теперь я застрял в том, как разобрать ее и создать файл. json из поля, которые я хочу.

Это то, что я имею до сих пор

@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7.1')
@Grab('oauth.signpost:signpost-core:1.2.1.2')
@Grab('oauth.signpost:signpost-commonshttp4:1.2.1.2')

import groovyx.net.http.RESTClient
import groovyx.net.http.Method
import static groovyx.net.http.ContentType.*
import groovyx.net.http.HttpResponseException
import groovy.json.JsonBuilder
import groovy.json.JsonOutput
import groovy.json.*

// User Credentials
def jiraAuth = ""

// JIRA Endpoints
def jiraUrl = "" //Dev
def jiraUrl = "" //Production

// Tempo API Tokens
//def tempoApiToken = "" //Dev
//def tempoApiToken = "" //Production

// Define Weekly Date Range
def today = new Date()
def lastPeriodStart = today - 8
def lastPeriodEnd = today - 2
def dateFrom = lastPeriodStart.format("yyyy-MM-dd")
def dateTo = lastPeriodEnd.format("yyyy-MM-dd")

def jiraClient = new RESTClient(jiraUrl)
jiraClient.ignoreSSLIssues()

def headers = [
    "Authorization"    : "Basic " + jiraAuth,
    "X-Atlassian-token": "no-check",
    "Content-Type"     : "application/json"
]

def response = jiraClient.get(
    path: "",
    query: [
        tempoApiToken: "${tempoApiToken}",
        format: "xml",
        dateFrom: "${dateFrom}",
        dateTo: "${dateTo}",
        addUserDetails: "true",
        addApprovalStatus: "true",
        addIssueSummary: "true"
    ],
    headers: headers
    ) { response, worklogs ->

    println "Processing..."

    // Start building the Output - Creates a Worklog Map
    worklogs.worklog.each { worklognodes ->

        def workLog = convertToMap(worklognodes)

        // Print out the Map
        println (workLog)
    }
}

// Helper Method
def convertToMap(nodes) {
    nodes.children().collectEntries {
        if (it.name() == 'user-prop') {
            [it['@key'], it.childNodes() ? convertToMap(it) : it.text()]
        } else {
            [it.name(), it.childNodes() ? convertToMap(it) : it.text()]
        }
    }
}

Меня интересует только разбор следующих полей для каждого узла:

<worklogs>
    <worklog>
        <hours>
        <work_date>
        <billing_key>
        <customField_11218>
        <issue_summary>
        <user_details>
            <full_name>
            <user-prop key="auto_approve_timesheet">
            <user-prop key="it_leadership">
            <user-prop key="resource_manager">
            <user-prop key="team">
            <user-prop key="cris_id">
            <user-prop key="iqn_id">
        <approval_status>
    </worklog>
    ...
</worklogs>

Я пробовал следующее: 1. Преобразование workLog в json строку (JsonOutput.to Json) и затем преобразование json строки в prettyPrint (JsonOutput.prettyPrint) - но это просто возвращает коллекцию. json ответы, с которыми я ничего не могу сделать (мыслительный процесс был, это настолько хорошо, насколько я могу получить, и я просто буду использовать конвертер. json в .csv и избавлюсь от того, что я не хочу) - это не то решение, которое я в конечном итоге хочу. 2. Печать карты workLog просто возвращает маленькие коллекции, с которыми я ничего не могу сделать. 3. Создайте новый файл, используя File и создав файл. json с workLog, но, опять же, он не переводите хорошо.

Результаты println для workLog здесь (просто чтобы каждый мог видеть, что ответ удерживается и карта соответствует ответу XML).

[worklog_id: , jira_worklog_id: , issue_id: , issue_key: , hours: , work_date: , username: , staff_id: , billing_key: , billing_attributes: , activity_id: , activity_name: , work_description: , parent_key: , reporter: , external_id:, external_tstamp:, external_hours: , external_result:, customField_11218: , hash_value: , issue_summary: , user_details:[full_name: , email: , auto_approve_timesheet: , cris_id: , iqn_gl_approver: , iqn_gl_string: , iqn_id: , is_contractor: , is_employee: , it_leadership: , primary_role: , resource_manager: , team: ], approval_status: , timesheet_approval:[status: ]]

Я был бы очень признателен, если бы кто-нибудь мог предложить некоторые идеи о том, как двигаться вперед, или даже документацию, в которой есть хорошие примеры того, чего я пытаюсь достичь (документации по Apache крайне не хватает в примерах, в моем мнение).

1 Ответ

0 голосов
/ 01 мая 2020

Это еще не все. Но я смог получить файл JSON, созданный с помощью XML и карты. Оттуда я могу просто использовать файл. json для создания .csv, а затем избавиться от ненужных столбцов.

// Define Weekly Date Range
def today = new Date()
def lastPeriodStart = today - 8
def lastPeriodEnd = today - 2
def dateFrom = lastPeriodStart.format("yyyy-MM-dd")
def dateTo = lastPeriodEnd.format("yyyy-MM-dd")

def jiraClient = new RESTClient(jiraUrl)
jiraClient.ignoreSSLIssues()

// Creates and Begins the File
File file = new File("${dateFrom}_RPT05.json")
    file.write("")
    file.append("[\n")

// Defines the File
def arrplace = 0
def arrsize = 0

def headers = [
    "Authorization"    : "Basic " + jiraAuth,
    "X-Atlassian-token": "no-check",
    "Content-Type"     : "application/json"
]

def response = jiraClient.get(
    path: "/plugins/servlet/tempo-getWorklog/",
    query: [    
        tempoApiToken: "${tempoApiToken}",
        format: "xml",
        dateFrom: "${dateFrom}",
        dateTo: "${dateTo}",
        addUserDetails: "true",
        addApprovalStatus: "true",
        addIssueSummary: "true"
    ], 
    headers: headers
    ) { response, worklogs ->

    println "Processing..."

    // Gets Size of Array
    worklogs.worklog.each { worklognodes ->
    arrsize = arrsize+1 }

    // Start Building the Output - Creates a Worklog Map 
    worklogs.worklog.each { worklognodes ->
        worklognodes = convertToMap(worklognodes)

        // Convert Map to a JSON String
        def json_str = JsonOutput.toJson(worklognodes)

        // Adds Row to File
        file.append(json_str)
        arrplace = arrplace+1
        if(arrplace<arrsize)
        {file.append(",")}
        file.append("\n")
        print "."
        }
    }

    file.append("]")

// Helper Method
def convertToMap(nodes) {
    nodes.children().collectEntries {
        if (it.name() == 'user-prop') {
            [it['@key'], it.childNodes() ? convertToMap(it) : it.text()]
        } else {
            [it.name(), it.childNodes() ? convertToMap(it) : it.text()]
        }
    }
}

Вывод представляет собой коллекцию / массив рабочих журналов.

...