2012-10-04 3 views
7

XML 입력을 받아서 사용자 정의 XML 출력을 반환해야하는 SOAP 웹 서비스를 설정 중입니다. 이 모든 것은 WSDL에서 정의됩니다. 나는 누군가가 내 목표를 달성하지 못하게하는 버그가 있다고 말할 때까지 soapServer를 적용한다 :-)).soapServer 응답에서 사용자 정의 XML 응답을 반환하는 방법은 무엇입니까?

사용자 지정 XML을 아직 반환하지 못했습니다. 표준 XML 요소 인 "Response"와 동일한 표준 루트 요소 이름을 사용하여 WSDL을 기반으로하는 결과를 얻었습니다. 실은 그게 저를 놀라게합니다. 부차적 인 질문으로 나는 그것이 왜 영향을받을 수 있는지 궁금합니다. 물론 응답이 생성 될 때 WSDL 정의가 어떻게 든 사용되는 것은 좋은 일이지만, 말했듯이 응답에서 사용자 정의 XML을 얻는 방법을 알지 못합니다.

나는이 늘어나는만큼 가지고 :

WSDL

<?xml version="1.0" encoding="UTF-8"?> 
<definitions 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://pse/" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    name="PSE" 
    targetNamespace="http://pse/"> 
    <types> 
     <xs:schema> 
      <xs:import namespace="http://pse/" schemaLocation="PSE.xsd"/> 
     </xs:schema> 
    </types> 
    <message name="MI102Req"> 
     <part name="cdhead" type="tns:cdhead_T"/> 
     <part name="instr" type="tns:instr_T"/> 
    </message> 
    <message name="Res"> 
     <part name="cdhead" type="tns:cdhead_T"/> 
    </message> 
    <portType name="MIPortType"> 
     <operation name="mi102"> 
      <input message="tns:MI102Req"/> 
      <output message="tns:Res"/> 
     </operation> 
    </portType> 
    <binding name="MIBinding" type="tns:MIPortType"> 
     <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> 
     <operation name="mi102"> 
      <soap:operation soapAction="http://www.testURL/test_soap.php#mi102"/> 
      <input> 
       <soap:body use="literal" namespace="http://pse/"/> 
      </input> 
      <output> 
       <soap:body use="literal" namespace="http://pse/"/> 
      </output> 
     </operation> 
    </binding> 
    <service name="PSE"> 
     <port name="MIPortType" binding="tns:MIBinding"> 
      <soap:address location="http://www.testURL/test_soap.php"/> 
     </port> 
    </service> 
</definitions> 

입력 XML

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> 
    <Body> 
     <mi102 xmlns="http://pse"> 
      <cdhead version="13"/> 
      <instr/> 
     </mi102> 
    </Body> 
</Envelope> 

현재 PHP

위에서 사용
<?php 
    class PSE { 
     function mi102 ($stdClassInput) { 
      $inp = file_get_contents ('php://input'); 
      $xml = simplexml_load_string ($inp); // Envelope 
      $ch = $xml -> children(); 
      $elt1 = $ch [0]; // Body 
      $ch = $elt1 -> children(); 
      $elt2 = $ch [0]; //mi102 

      $xslt = new XSLTProcessor(); 
      $xslt -> registerPHPFunctions(); 
      $xslt -> importStylesheet (DOMDocument::load ('test.xslt')); 
      $dom = $xslt -> transformToDoc (DOMDocument::loadXML ($elt2 -> asXML())); 

      $result = new SoapVar ($dom -> saveXML(), XSD_ANYXML); 
      return ($result); 
     } 
    } 

    ini_set("soap.wsdl_cache_enabled", "0"); 
    $server = new SoapServer ("test.wsdl"); 
    $server -> setClass ('PSE'); 
    $server -> setObject (new PSE()); 
    $server -> handle(); 
?> 

XSLT는 속성을 변경 한 것입니다 - 및 온도 변화 (:-) 단지의 경우) 항상 서버에 의해 반환되는

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pse="http://pse"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="pse:mi102"> 
     <mi102Response> 
      <xsl:apply-templates/> 
     </mi102Response> 
    </xsl:template> 

    <xsl:template match="pse:cdhead"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@*"> 
     <xsl:copy/> 
    </xsl:template> 

    <xsl:template match="@version"> 
     <xsl:attribute name="version">14</xsl:attribute> 
    </xsl:template> 

    <xsl:template match="*"/> 

</xsl:stylesheet> 

에 루트 이름은 내가 반환 XML이

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://pse/"> 
    <SOAP-ENV:Body> 
     <ns1:mi102Response> 
      <cdhead version="14"/> 
     </ns1:mi102Response> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

같은 될 것으로 기대하지만 그 대신이

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://pse/"> 
    <SOAP-ENV:Body> 
     <ns1:mi102Response/> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 
입니다

위의 PHP에서 $ dom 내용을 디버깅하면 리턴하려고하는 XML이 정확하게 표시됩니다 (입력 된 것과 마찬가지로 SOAP Envelope/Body로 래핑 됨).

<?xml version="1.0" encoding="UTF-8"?> 
<mi102Response xmlns:pse="http://pse"> 
    <cdhead xmlns="http://pse" version="14"/> 
</mi102Response> 

어디서 잘못 되었나요? 반환 된 http 응답 콘텐츠에 맞춤 XML을 가져 오는 방법은 무엇입니까?

답변

7

피어!

내가 틀린 것을 발견 할 때까지 이것은 몇 가지 재 시도와 인터넷 검색을 필요로했습니다.
나는 버그 SoapVar로 분류 될 수 있다고 생각합니다.

SoapVar에서 XML 문자열을 완벽하게 분석 할 수 있지만 문자열에 <?xml version="1.0" encoding="UTF-8"?>과 같은 XML 선언이 포함되어 있으면 그렇게 할 수 없다는 것을 발견했습니다. DOMDocument 또는 SimpleXMLElement이있는 경우 먼저 SoapVar로 문자열을 구문 분석하기 전에 선언을 제거해야합니다.

DOMDocument에 대해 saveXML에 적용 할 수 있습니다.이 매개 변수는 dom 자체에서 생성 된 변수 DOMNode과 동일하지만 임의의 노드를 선택하지만 대개 이것은 루트 노드입니다.

$nodes = $dom -> getElementsByTagName ('cdhead'); 
$node = $nodes -> item(0); 

$result = new SoapVar ($dom -> saveXML($node), XSD_ANYXML); 

그리고 지금 내 결과가 OK입니다 : 내 서버 PHP에서

, 나는 다음과 같은 추가 반환 된 XML의 루트 이름으로

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://pse/"> 
<SOAP-ENV:Header/> 
<SOAP-ENV:Body> 
    <ns1:mi102Response> 
     <cdhead version="14"/> 
    </ns1:mi102Response> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

- 나는 확신합니다 그것을 (SoapVar에 의해 생성 된 표준 mi102Response가 아닌) 원하는 것으로 변경하는 방법을 찾아라 !!

관련 문제