将WSResponse解析为对象

时间:2014-10-14 13:08:08

标签: xml playframework

我目前正在接收来自我调用的SOAP调用的WSResponse,并且我正在尝试解析响应。这是响应的样子。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ns0:HelpDesk_QueryList_ServiceResponse xmlns:ns0="urn:HPD_IncidentInterface_WS">
            <ns0:getListValues>
                <ns0:Assigned_Group>Operations Tier 1</ns0:Assigned_Group>
                <ns0:Assigned_Group_Shift_Name />
                <ns0:Assigned_Support_Company>HTEN</ns0:Assigned_Support_Company>
                <ns0:Assigned_Support_Organization>Operations</ns0:Assigned_Support_Organization>
                <ns0:Assignee>App Admin</ns0:Assignee>
                <ns0:Categorization_Tier_1>Equipment</ns0:Categorization_Tier_1>
                <ns0:Categorization_Tier_2 />
                <ns0:Categorization_Tier_3 />
                <ns0:City>FakeCity</ns0:City>
                <ns0:Closure_Manufacturer />
                <ns0:Closure_Product_Category_Tier1 />
                <ns0:Closure_Product_Category_Tier2 />
                <ns0:Closure_Product_Category_Tier3 />
                <ns0:Closure_Product_Model_Version />
                <ns0:Closure_Product_Name />
                <ns0:Company>FakeCompany</ns0:Company>
                <ns0:Contact_Company>FakeCompany</ns0:Contact_Company>
                <ns0:Contact_Sensitivity>Standard</ns0:Contact_Sensitivity>
                <ns0:Country>United States</ns0:Country>
                <ns0:Department />
                <ns0:Summary>HTEN-FakeCompany-0001</ns0:Summary>
                <ns0:Notes>----Event Information-------
    Event: highCPU
    HostName: HTEN-FakeCompany-0001
    Severity: CRITICAL
    Event Time: 4/10/2014 13:23:00
    Message: highCPU HTEN-FakeCompany-0001 CPU has been greater than 75% for the last 15 minutes

    -----Event Cat Information-----
    Device Type: 
    Company: FakeCompany
    Ticket Type: 
    Service Impact: 
    Wiki Article:  

    --Assigned to the Following Group--</ns0:Notes>
                <ns0:First_Name>FakeCompany</ns0:First_Name>
                <ns0:Impact>2-Significant/Large</ns0:Impact>
                <ns0:Incident_Number>INC000000057006</ns0:Incident_Number>
                <ns0:Internet_E-mail />
                <ns0:Last_Name>Event</ns0:Last_Name>
                <ns0:Manufacturer />
                <ns0:Middle_Initial />
                <ns0:Organization />
                <ns0:Phone_Number>###</ns0:Phone_Number>
                <ns0:Priority>High</ns0:Priority>
                <ns0:Priority_Weight>20</ns0:Priority_Weight>
                <ns0:Product_Categorization_Tier_1 />
                <ns0:Product_Categorization_Tier_2 />
                <ns0:Product_Categorization_Tier_3 />
                <ns0:Product_Model_Version />
                <ns0:Product_Name />
                <ns0:Region>North America</ns0:Region>
                <ns0:Reported_Source>Other</ns0:Reported_Source>
                <ns0:Resolution />
                <ns0:Resolution_Category>LEC</ns0:Resolution_Category>
                <ns0:Resolution_Category_Tier_2>L3</ns0:Resolution_Category_Tier_2>
                <ns0:Resolution_Category_Tier_3>CABLE CUT</ns0:Resolution_Category_Tier_3>
                <ns0:Service_Type>Infrastructure Event</ns0:Service_Type>
                <ns0:Site>FakeCity NOCP</ns0:Site>
                <ns0:Site_Group>North America</ns0:Site_Group>
                <ns0:Status>Closed</ns0:Status>
                <ns0:Status_Reason />
                <ns0:Urgency>2-High</ns0:Urgency>
                <ns0:VIP>No</ns0:VIP>
                <ns0:ServiceCI />
                <ns0:ServiceCI_ReconID />
                <ns0:HPD_CI>HTEN-FakeCompany-0001</ns0:HPD_CI>
                <ns0:HPD_CI_ReconID>RE005056A12C40QdJGUwmzNHAQLroA</ns0:HPD_CI_ReconID>
                <ns0:HPD_CI_FormName>BMC_BUSINESSSERVICE</ns0:HPD_CI_FormName>
                <ns0:z1D_CI_FormName>AST:BusinessService</ns0:z1D_CI_FormName>
            </ns0:getListValues>
            <ns0:getListValues>
                <ns0:Assigned_Group>Operations Tier 1</ns0:Assigned_Group>
                <ns0:Assigned_Group_Shift_Name />
                <ns0:Assigned_Support_Company>HTEN</ns0:Assigned_Support_Company>
                <ns0:Assigned_Support_Organization>Operations</ns0:Assigned_Support_Organization>
                <ns0:Assignee>FakeCompany Customer</ns0:Assignee>
                <ns0:Categorization_Tier_1 />
                <ns0:Categorization_Tier_2 />
                <ns0:Categorization_Tier_3 />
                <ns0:City>FakeCity</ns0:City>
                <ns0:Closure_Manufacturer />
                <ns0:Closure_Product_Category_Tier1 />
                <ns0:Closure_Product_Category_Tier2 />
                <ns0:Closure_Product_Category_Tier3 />
                <ns0:Closure_Product_Model_Version />
                <ns0:Closure_Product_Name />
                <ns0:Company>FakeCompany</ns0:Company>
                <ns0:Contact_Company>FakeCompany</ns0:Contact_Company>
                <ns0:Contact_Sensitivity>Standard</ns0:Contact_Sensitivity>
                <ns0:Country>United States</ns0:Country>
                <ns0:Department />
                <ns0:Summary>na</ns0:Summary>
                <ns0:Notes />
                <ns0:First_Name>FakeCompany</ns0:First_Name>
                <ns0:Impact>3-Moderate/Limited</ns0:Impact>
                <ns0:Incident_Number>INC000000057016</ns0:Incident_Number>
                <ns0:Internet_E-mail />
                <ns0:Last_Name>Event</ns0:Last_Name>
                <ns0:Manufacturer />
                <ns0:Middle_Initial />
                <ns0:Organization />
                <ns0:Phone_Number>###</ns0:Phone_Number>
                <ns0:Priority>Medium</ns0:Priority>
                <ns0:Priority_Weight />
                <ns0:Product_Categorization_Tier_1 />
                <ns0:Product_Categorization_Tier_2 />
                <ns0:Product_Categorization_Tier_3 />
                <ns0:Product_Model_Version />
                <ns0:Product_Name />
                <ns0:Region>North America</ns0:Region>
                <ns0:Reported_Source>Other</ns0:Reported_Source>
                <ns0:Resolution />
                <ns0:Resolution_Category>NONE</ns0:Resolution_Category>
                <ns0:Resolution_Category_Tier_2>FALSE OUTAGE</ns0:Resolution_Category_Tier_2>
                <ns0:Resolution_Category_Tier_3>FALSE OUTAGE</ns0:Resolution_Category_Tier_3>
                <ns0:Service_Type>Infrastructure Event</ns0:Service_Type>
                <ns0:Site>FakeCity NOCP</ns0:Site>
                <ns0:Site_Group>North America</ns0:Site_Group>
                <ns0:Status>Closed</ns0:Status>
                <ns0:Status_Reason />
                <ns0:Urgency>3-Medium</ns0:Urgency>
                <ns0:VIP>No</ns0:VIP>
                <ns0:ServiceCI />
                <ns0:ServiceCI_ReconID />
                <ns0:HPD_CI />
                <ns0:HPD_CI_ReconID />
                <ns0:HPD_CI_FormName />
                <ns0:z1D_CI_FormName />
            </ns0:getListValues>
        </ns0:HelpDesk_QueryList_ServiceResponse>
    </soapenv:Body>
</soapenv:Envelope>

我不需要所有的元素,但我需要的是我想要放入POJO。到目前为止,我有什么更好的办法吗?这就是我所做的。

WSResponse wsresponse = request.post(soapRequest).get(TIMEOUT);
Document response = wsresponse.asXml();
List < TroubleTicket > tickets = Lists.newArrayList();
Node node = response.getElementsByTagNameNS("*", QUERY_LIST_RESPONSE).item(0);
NodeList children = node.getChildNodes();
Logger.info("Parsing tickets from response, found " + children.getLength() + " tickets.");
for (int counter = 0; counter < children.getLength(); counter++) {
    NodeList grandChildren = children.item(counter).getChildNodes();
    for (int childCounter = 0; childCounter < grandChildren.getLength(); childCounter++) {
        TroubleTicket ticket = new TroubleTicket();
        String element = grandChildren.item(childCounter).getNodeName();
        String elementText = grandChildren.item(childCounter).getTextContent();
        switch (element) {
            case "Summary":
                ticket.setSummary(elementText);
                break;
            case "Notes":
                ticket.setNotes(elementText);
                break;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

MIkCode's comment之后,我还建议使用Scala将XML解组为模型对象。当您使用面向Scala的Play Framework时,至少可以探索使用Scala进行XML处理的选项。

这是Scala中XML处理的粗略说明。即使您不熟悉Scala,希望您可以看到该处理基于使用类似XPath的选择器,并且代码比使用Java中的Document API更简洁。

网络服务电话

WSResponse wsResponse = request.post(soapRequest).get(TIMEOUT);
HelpDeskServiceResponse response = new HelpDeskServiceResponse(wsResponse.getBody())
// response.tickets() will now give you a Scala collection of tickets.

HelpDeskServiceResponse.scala

import scala.xml.XML

class HelpDeskServiceResponse(xml : String) {

  lazy val xmlDoc = XML.load(xml)

  // Matches on any 'getListValues' descendants and transforms each matching 
  // element to a ticket object
  lazy val tickets = (xmlDoc \\ "getListValues").map(node => new HelpDeskTicket(node))

}

HelpDeskTicket.scala

import scala.xml.Node

class HelpDeskTicket(node : Node) {

  lazy val summary = node \ "Summary"

  lazy val notes = node \ "Notes"

}

答案 1 :(得分:1)

我最终做的是获取WSResponse并调用response.asXml();这返回了一个XML文档,我循环查找我需要的字段,并保存在字符串列表中。然后,我构建了Json对象,以便在循环响应时将其返回给客户端。

Node node = response.getElementsByTagNameNS("*", elementTagName).item(0);
NodeList children = node.getChildNodes();
ArrayNode responseTickets = Json.newObject().arrayNode();

for (int counter = 0; counter < children.getLength(); counter++) {
ObjectNode ticketNode = getTicketFromResponse(children.item(counter).getChildNodes(), responseFields);
if (ticketNode.size() != 0) {
   responseTickets.add(ticketNode);
   }
}
return responseTickets;

getTicketsFromResponse方法:

ObjectNode ticketNode = Json.newObject();
    for (int childCounter = 0; childCounter < nodeList.getLength(); childCounter++) {
        String element = nodeList.item(childCounter).getNodeName();
        String elementText = nodeList.item(childCounter).getTextContent();
        element = element.substring(4, element.length());
        if (responseFields.contains(element)) {
            ticketNode.put(element, elementText);
            if (SUMMARY_FIELD.equals(element) && !Strings.isEmpty(elementText)) {
                // Retrieve the id of the resource
                try {
                    Long id = null;
                    Matcher matcher = Pattern.compile(SERVICE_ID_PATTERN).matcher(elementText);
                    if (matcher.find()) {
                        String matched = matcher.group(0);
                        Matcher numberMatcher = Pattern.compile("\\d+").matcher(matched);
                        if (numberMatcher.find()) {
                            id = Long.parseLong(numberMatcher.group(0));
                            Service service = Service.findByIdNotNull(id);
                            ticketNode.put(SERVICE_NAME_FIELD,
                                    String.format(SERVICE_NAME_FORMAT, service.getName(), service.getUSI()));
                        }
                    }
                    ticketNode.put(SERVICE_ID_FIELD, id);
                } catch (NullPointerException exception) {
                    Logger.error("Unable to get the service for the configuration item", exception);
                } catch (NumberFormatException exception) {
                    Logger.error("Unable to parse the id from the summary field. ");
                } catch (ResourceNotFoundException exception) {
                    Logger.error("Unable to get the service.", exception);
                }
            } else if (SUBMIT_DATE_FIELD.equals(element) && !Strings.isEmpty(elementText)) {
                try {
                    Date submitDate = new SimpleDateFormat(RESPONSE_DATE_FORMAT).parse(elementText);
                    elementText = new SimpleDateFormat(SKYLIGHT_DATE_FORMAT).format(submitDate);
                    ticketNode.put(element, elementText);
                } catch (ParseException exception) {
                    Logger.error("Unable to parse the submit date. ", exception);
                }
            }
        }
    }
    return ticketNode;