Сценарий Я реализовал API, который делает мыльный вызов внешней службе. Мне нужно преобразовать ответ из xml в json (что на самом деле и происходит). Но почему-то я не могу преобразовать вложенные узлы xml в json.
API
<?xml version = "1.0" encoding = "UTF-8"?>
<api context = "/nadra" name = "NadraVerification" xmlns = "http://ws.apache.org/ns/synapse">
<resource methods = "POST">
<inSequence>
<payloadFactory media-type = "xml">
<format>
<soapenv:Envelope xmlns:nad = "http://XXXX.Verification" xmlns:soapenv = "http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<nad:GetCitizenDemographics>
<nad:franchizeID>XXX</nad:franchizeID>
<nad:xml_request_data><![CDATA[
<CITIZEN_VERIFICATION><USER_VERIFICATION><USERNAME>XXXX</USERNAME><PASSWORD>XXXX</PASSWORD></USER_VERIFICATION><REQUEST_DATA><TRANSACTION_ID>$4</TRANSACTION_ID><SESSION_ID></SESSION_ID><CITIZEN_NUMBER>$5</CITIZEN_NUMBER><CONTACT_NUMBER>$6</CONTACT_NUMBER><AREA_NAME>$7</AREA_NAME></REQUEST_DATA></CITIZEN_VERIFICATION>
]]></nad:xml_request_data>
</nad:GetCitizenDemographics>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator = "json" expression = "$.transactionId"/>
<arg evaluator = "json" expression = "$.citizenNo"/>
<arg evaluator = "json" expression = "$.contactNo"/>
<arg evaluator = "json" expression = "$.areaName"/>
</args>
</payloadFactory>
<header name = "Action" scope = "default" value = "http://XXXX.XXXX.XXXX/ICitizenVerification/GetCitizenDemographics"/>
<send>
<endpoint>
<address format = "soap11" uri = "https://verification.nadra.gov.pk/bioverisys/xml">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</address>
</endpoint>
</send>
</inSequence>
<outSequence>
<property name = "messageType" scope = "axis2" type = "STRING" value = "application/json"/>
<payloadFactory media-type = "json">
<format>
{
"status" : "success"
"response": $1
}</format>
<args>
<arg evaluator = "json" expression = "$.GetCitizenDemographicsResponse.GetCitizenDemographicsResult"/>
</args>
</payloadFactory>
<respond/>
</outSequence>
<faultSequence>
<payloadFactory media-type = "json">
<format>
{
"status" : "failure"
}</format>
<args/>
</payloadFactory>
</faultSequence>
</resource>
</api>
Ответ от внешней службы после преобразования XML в JSON
{
"GetCitizenDemographicsResponse": {
"GetCitizenDemographicsResult": "<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<CITIZEN_VERIFICATION xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <RESPONSE_DATA>\r\n <RESPONSE_STATUS>\r\n <CODE>100</CODE>\r\n
<MESSAGE>successful</MESSAGE>\r\n </RESPONSE_STATUS>\r\n <SESSION_ID>00001343681312</SESSION_ID>\r\n
<CITIZEN_NUMBER>XXXX</CITIZEN_NUMBER>\r\n <PERSON_DATA>\r\n <NAME>ایوب جمال</NAME>\r\n
<FATHER_HUSBAND_NAME>XXX</FATHER_HUSBAND_NAME>\r\n <PRESENT_ADDRESS>XXXX</PRESENT_ADDRESS>\r\n
<PERMANANT_ADDRESS>XXXX</PERMANANT_ADDRESS>\r\n <DATE_OF_BIRTH>1996-01-10</DATE_OF_BIRTH>\r\n
<GENDER>male</GENDER>\r\n <EXPIRY_DATE>2030-07-11</EXPIRY_DATE>\r\n </PERSON_DATA>\r\n
</RESPONSE_DATA>\r\n</CITIZEN_VERIFICATION>"
}
}
Фактический ответ
<s:Envelope xmlns:s = "http://schemas.xmlsoap.org/soap/envelope/"><s:Body><GetCitizenDemographicsResponse xmlns = "http://NADRA.Citizen.Verification"><GetCitizenDemographicsResult><?xml version = "1.0" encoding = "utf-16"?>
<CITIZEN_VERIFICATION xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
<RESPONSE_DATA>
<RESPONSE_STATUS>
<CODE>107</CODE>
<MESSAGE>invalid citizen nummber</MESSAGE>
</RESPONSE_STATUS>
<SESSION_ID />
<CITIZEN_NUMBER>$5</CITIZEN_NUMBER>
</RESPONSE_DATA>
</CITIZEN_VERIFICATION></GetCitizenDemographicsResult></GetCitizenDemographicsResponse></s:Body></s:Envelope>
Вопрос Мой точный вопрос: как я могу преобразовать вложенный xml в json? Поскольку он преобразовал первые два узла xml, но третий узел xml не был преобразован.
Поскольку вы используете фабрику полезной нагрузки для изменения ответа, вы можете использовать выражение XPath для извлечения значений из конечной точки мыла. Вам не нужно явно преобразовывать ответ SOAP в JSON с помощью свойства messageType
перед фабрикой полезной нагрузки.
messageType
Обновить ответ
Согласно ответу серверной части, в теле SOAP он объявил тег <?xml version = "1.0" encoding = "UTF-8"?>
перед элементом CITIZEN_VERIFICATION
. Из-за этого нам нужно сначала присвоить его свойству с типом OM
, а затем использовать его в фабрике полезной нагрузки. Поскольку у нас есть пространство имен, определенное для GetCitizenDemographicsResponse
, нам также нужно добавить тег пространства имен в посредник свойства.
Вариант 1: с пространством имен
<property type = "OM" xmlns:ns = "http://NADRA.Citizen.Verification" expression = "//ns:GetCitizenDemographicsResponse/*" name = "Payload"/>
Или вы можете использовать функцию local-name()
, чтобы получить значение без определения пространства имен в посреднике свойств.
Вариант 2: без определения пространства имен
<property type = "OM" expression = "//*[local-name()='GetCitizenDemographicsResult']" name = "Payload"/>
<outSequence>
<property type = "OM" xmlns:ns = "http://NADRA.Citizen.Verification" expression = "//ns:GetCitizenDemographicsResponse/*" name = "Payload"/>
<payloadFactory media-type = "json">
<format>
{
"status" : "success",
"response": $1
}
</format>
<args>
<arg expression = "$ctx:Payload" />
</args>
</payloadFactory>
<respond/>
</outSequence>
если вы видите ответ от внешней службы, у него также есть \r\n. Это вызывает проблему?
Можете ли вы также поделиться полным ответом от внешней службы?
@sonaJ Я также обновил вопрос, указав фактический ответ.
@sonaJ мне нужно преобразовать теги xml в json
@AyubJamal Я обновил ответ. Не могли бы вы проверить это сейчас?
@sonaJ я проверил, теперь это дает мне ошибку: ОШИБКА {SequenceMediator} - {api: NadraVerification} com.ctc.wstx.exc.WstxEOFException: Неожиданный EOF в прологе в [row, col {unknown-source}]: [1 ,0] org.apache.axiom.om.OMException: com.ctc.wstx.exc.WstxEOFException: Неожиданный EOF в прологе в [строка, столбец {неизвестный источник}]: [1,0]
@AyubJamal Нам также нужно иметь пространство имен в посреднике свойств. Я обновил ответ. Надеюсь, это решит вашу проблему
это дает мне ответ API, подобный этому { "status": "success" "response": }