XDTO XML WSDL XSD и остальные 33 богатыря - нужна помощь

  1. 9 г. назад
    28.03.2015 22:48:43 отредактировано ЗлобнийМальчик

    to be deleted

  2. Преамбула: я где то год назад думал, что имплементация SOAP в Сапе - это кошмар на улице вязов, хуже которого ничего не бывает. Работая с вебсервисами в 1с, я начинаю понимать, что они друг друга стоят.

    Собственно, вопрос.
    Как в 1С преобразовать сложный тип к объектам языка?
    Есть PHP class который использует nusoap для создания вебсервисов

    <?php
    
    error_reporting(0);
    
    // Configuration
    require_once('../admin/config.php');
    require_once(DIR_SYSTEM . 'startup.php');
    require_once(DIR_SYSTEM . 'library/nusoap.php');
    //$registry = new Registry();
    
    date_default_timezone_set('Asia/Bangkok');
    
    
    // Create SOAP Server
    $server = new soap_server();
    $server->configureWSDL("test_service", "http://www.example.com/test_service");
    
    // Example "hello" function
    function hello($username) {
        if ($username == 'admin') {
            return "Welcome back, Boss";
        }
        else {
            return "Hello, $username";
        }
    }
    
    $server->register("hello", array("username" => "xsd:string"), array("return" => "xsd:string"), "http://www.example.com", "", "", "", "say hi to the caller"
    );
    
    // Example "intCount" function (return array)
    function int_count($from, $to) {
        $out = array();
        for ($i = $from; $i <= $to; $i++) {
            $out[] = $i;
        }
        return $out;
    }
    
    function int_count_matrix($from, $to) {
        $out = array();
    
    ////lets create a matrix
    ////x coordinate
        for ($x = $from; $x <= $to; $x++) {
            $out_x = array();
            for ($y = $from; $y <= $to; $y++) {
                $out_x = x + y;
            }
            $out[] = $out_x;
        }
    
    
        return $out;
    }
    
    $server->wsdl->addComplexType(
            'intArray', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(
        array(
            'ref' => 'SOAP-ENC:arrayType',
            'wsdl:arrayType' => 'xsd:integer[]'
        )
            ), 'xsd:integer'
    );
    
    $server->register("int_count", array("from" => "xsd:integer", "to" => "xsd:integer"), array("return" => "tns:intArray"), "http://www.example.com", "", "", "", "count from 'from' to 'to'"
    );
    
    // Example "getUserInfo" function (return struct and fault)
    function get_user_info($userId) {
        if ($userId == 1) {
            return array(
                'id' => 1,
                'username' => 'testuser',
                'email' => 'testuser@example.com'
            );
        }
        else {
            return new soap_fault('SOAP-ENV:Server', '', 'Requested user not found', '');
        }
    }
    
    $server->wsdl->addComplexType(
            'userInfo', 'complextType', 'struct', 'sequence', '', array(
        'id' => array('name' => 'id', 'type' => 'xsd:integer'),
        'username' => array('name' => 'username', 'type' => 'xsd:string'),
        'email' => array('name' => 'email', 'type' => 'xsd:string')
            )
    );
    
    $server->register("get_user_info", array("userId" => "xsd:integer"), array("return" => "tns:userInfo"), "http://www.example.com", "", "", "", "get info for user"
    );
    // Get our posted data if the service is being consumed
    // otherwise leave this data blank.
    $POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
    
    // pass our posted data (or nothing) to the soap service
    $server->service($POST_DATA);
    exit();
    ?>
    
    

    класс генерирует при обращении к нему вот такой WSDL

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.example.com/test_service" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.example.com/test_service">
    <types>
    <xsd:schema targetNamespace="http://www.example.com/test_service"
    >
     <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
     <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
    </xsd:schema>
    </types>
    <message name="helloRequest">
      <part name="username" type="xsd:string" /></message>
    <message name="helloResponse">
      <part name="return" type="xsd:string" /></message>
    <message name="get_user_infoRequest">
      <part name="userId" type="xsd:integer" /></message>
    <message name="get_user_infoResponse">
      <part name="return" type="tns:userInfo" /></message>
    <portType name="test_servicePortType">
      <operation name="hello">
        <documentation>say hi to the caller</documentation>
        <input message="tns:helloRequest"/>
        <output message="tns:helloResponse"/>
      </operation>
      <operation name="get_user_info">
        <documentation>get info for user</documentation>
        <input message="tns:get_user_infoRequest"/>
        <output message="tns:get_user_infoResponse"/>
      </operation>
    </portType>
    <binding name="test_serviceBinding" type="tns:test_servicePortType">
      <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="hello">
        <soap:operation soapAction="http://localhost/shop3/export/webservices_test.php/hello" style="rpc"/>
        <input><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
        <output><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
      </operation>
      <operation name="get_user_info">
        <soap:operation soapAction="http://localhost/shop3/export/webservices_test.php/get_user_info" style="rpc"/>
        <input><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
        <output><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
      </operation>
    </binding>
    <service name="test_service">
      <port name="test_servicePort" binding="tns:test_serviceBinding">
        <soap:address location="http://localhost/shop3/export/webservices_test.php"/>
      </port>
    </service>
    </definitions>
    

    из WSDL был выковырян XSD

    <xsd:schema xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.com/test_service" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/test_service">
    	<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"></xsd:import>
    	<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"></xsd:import>
    	<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/"></xsd:import>
    	<xsd:complexType name="intArray">
    		<xsd:complexContent>
    			<xsd:restriction base="SOAP-ENC:Array">
    				<xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:integer[]"></xsd:attribute>
    			</xsd:restriction>
    		</xsd:complexContent>
    	</xsd:complexType>
    	<xsd:complexType name="userInfo">
    		<xsd:sequence>
    			<xsd:element name="id" type="xsd:integer"></xsd:element>
    			<xsd:element name="username" type="xsd:string"></xsd:element>
    			<xsd:element name="email" type="xsd:string"></xsd:element>
    		</xsd:sequence>
    	</xsd:complexType>
    </xsd:schema>
    

    И WSDL и XSD были импортированы в конфигурацию.
    Пытаюсь вызвать веб сервис вот таким кодом

    	
    Proxy = WSСсылки.WSСсылка1.СоздатьWSПрокси("http://www.example.com/test_service","test_service","test_servicePort");
    	
    	Определения = WSСсылки.WSСсылка1.ПолучитьWSОпределения();	
    	
    	Answer =    Proxy.int_count(1,5);
    	
    	
    	
    	МойСериализаторXDTO = новый СериализаторXDTO(Определения.ФабрикаXDTO);
    	КакойТоРезультат = МойСериализаторXDTO.ПрочитатьXDTO(Answer);
    

    Падаю на

    {Форма.Форма.Форма(23)}: Ошибка при вызове метода контекста (ПрочитатьXDTO)
    	КакойТоРезультат = МойСериализаторXDTO.ПрочитатьXDTO(Answer);
    по причине:
    Ошибка преобразования данных XDTO:
    НачалоСвойства: {http://www.example.com/test_service}intArray	Форма: Элемент	Тип: {http://www.example.com/test_service}intArray
    по причине:
    Ошибка отображения типов:
    Отсутствует отображение для типа '{http://www.example.com/test_service}intArray'
    

    Когда пытаюсь вызвать вот таким кодом

    	
           Proxy = WSСсылки.WSСсылка1.СоздатьWSПрокси("http://www.example.com/test_service","test_service","test_servicePort");
    	
    	Определения = WSСсылки.WSСсылка1.ПолучитьWSОпределения();	
    	
    	Answer =    Proxy.int_count(1,5);
    	
    	КакойТоРезультат = СериализаторXDTO.ПрочитатьXDTO(Answer);
    

    Ошибка становится другая - но все равно остается

    {Форма.Форма.Форма(12)}: Ошибка при вызове метода контекста (ПрочитатьXDTO)
    КакойТоРезультат = СериализаторXDTO.ПрочитатьXDTO(Answer);
    по причине:
    Несоответствие типов XDTO:
    Тип '{http://www.example.com/test_service}intArray' не найден
    Тип принадлежит пакету, входящему в состав другой фабрики типов XDTO
    

    И я остаюсь в полном непонимании - как сказать одинэске чтобы она преобразовала intArray в массив?

    Ответы: (3)
  3. а почему я не вижу определения intArray в WDSL?

    Ответы: (4)
  4. ЗлобнийМальчик из WSDL был выковырян XSD

    каким образом?

  5. (2) да, наверное я не тот WSDL запостил. Извиняюсь

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.example.com/test_service" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.example.com/test_service">
    <types>
    <xsd:schema targetNamespace="http://www.example.com/test_service"
    >
     <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
     <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
     <xsd:complexType name="intArray">
      <xsd:complexContent>
       <xsd:restriction base="SOAP-ENC:Array">
        <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:integer[]"/>
       </xsd:restriction>
      </xsd:complexContent>
     </xsd:complexType>
     <xsd:complexType name="userInfo">
      <xsd:sequence>
       <xsd:element name="id" type="xsd:integer"/>
       <xsd:element name="username" type="xsd:string"/>
       <xsd:element name="email" type="xsd:string"/>
      </xsd:sequence>
     </xsd:complexType>
    </xsd:schema>
    </types>
    <message name="helloRequest">
      <part name="username" type="xsd:string" /></message>
    <message name="helloResponse">
      <part name="return" type="xsd:string" /></message>
    <message name="int_countRequest">
      <part name="from" type="xsd:integer" />
      <part name="to" type="xsd:integer" /></message>
    <message name="int_countResponse">
      <part name="return" type="tns:intArray" /></message>
    <message name="get_user_infoRequest">
      <part name="userId" type="xsd:integer" /></message>
    <message name="get_user_infoResponse">
      <part name="return" type="tns:userInfo" /></message>
    <portType name="test_servicePortType">
      <operation name="hello">
        <documentation>say hi to the caller</documentation>
        <input message="tns:helloRequest"/>
        <output message="tns:helloResponse"/>
      </operation>
      <operation name="int_count">
        <documentation>count from 'from' to 'to'</documentation>
        <input message="tns:int_countRequest"/>
        <output message="tns:int_countResponse"/>
      </operation>
      <operation name="get_user_info">
        <documentation>get info for user</documentation>
        <input message="tns:get_user_infoRequest"/>
        <output message="tns:get_user_infoResponse"/>
      </operation>
    </portType>
    <binding name="test_serviceBinding" type="tns:test_servicePortType">
      <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="hello">
        <soap:operation soapAction="http://localhost/shop3/test_1.php/hello" style="rpc"/>
        <input><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
        <output><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
      </operation>
      <operation name="int_count">
        <soap:operation soapAction="http://localhost/shop3/test_1.php/int_count" style="rpc"/>
        <input><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
        <output><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
      </operation>
      <operation name="get_user_info">
        <soap:operation soapAction="http://localhost/shop3/test_1.php/get_user_info" style="rpc"/>
        <input><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
        <output><soap:body use="encoded" namespace="http://www.example.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
      </operation>
    </binding>
    <service name="test_service">
      <port name="test_servicePort" binding="tns:test_serviceBinding">
        <soap:address location="http://localhost/shop3/test_1.php"/>
      </port>
    </service>
    </definitions>
    

    xsd был выковырян xmlspy

  6. Забил я короче на XDTO преобразования и воспользовался банальным кодом типа такого

    	
    Сервис = WSСсылки.Products.СоздатьWSПрокси("http://localhost/test_3.php?wsdl",  "WSDLTST", "WSDLTSTPort"); 
    	
    	// Ну и наконец-то вызовем наш метод 
    	value = Сервис.Method1();
    	
    	
    	For each element in value.list do
    		Сообщить(element.index);
    		Сообщить(element.size);		
    	enddo;
    

    Для вот такого WSDL

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost/soap/WSDLTST" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://localhost/soap/WSDLTST">
    <types>
    <xsd:schema targetNamespace="http://localhost/soap/WSDLTST"
    >
     <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
     <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
     <xsd:complexType name="Product">
      <xsd:all>
       <xsd:element name="index" type="xsd:int"/>
       <xsd:element name="size" type="xsd:string"/>
      </xsd:all>
     </xsd:complexType>
     <xsd:complexType name="ProductArray">
      <xsd:complexContent>
       <xsd:restriction base="SOAP-ENC:Array">
        <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="tns:Product[]"/>
       </xsd:restriction>
      </xsd:complexContent>
     </xsd:complexType>
    </xsd:schema>
    </types>
    <message name="Method1Request"></message>
    <message name="Method1Response">
      <part name="return" type="tns:ProductArray" /></message>
    <portType name="WSDLTSTPortType">
      <operation name="Method1">
        <documentation>bla bla bla</documentation>
        <input message="tns:Method1Request"/>
        <output message="tns:Method1Response"/>
      </operation>
    </portType>
    <binding name="WSDLTSTBinding" type="tns:WSDLTSTPortType">
      <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="Method1">
        <soap:operation soapAction="http://localhost/shop3/test_3.php/Method1" style="rpc"/>
        <input><soap:body use="encoded" namespace="http://localhost/api/tstserver.php" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
        <output><soap:body use="encoded" namespace="http://localhost/api/tstserver.php" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
      </operation>
    </binding>
    <service name="WSDLTST">
      <port name="WSDLTSTPort" binding="tns:WSDLTSTBinding">
        <soap:address location="http://localhost/shop3/test_3.php"/>
      </port>
    </service>
    </definitions>
    
    
    Ответы: (10)
  7. PHP не нужен.

    XML, XSLT, WDSL, XSD не нужны.

    JSON, YAML, Tree и Rest сервисы рулят.

    Ответы: (7) (11)
  8. (6) слава богу! Вы напишите свой интернет с гейшами и шоколадом. "Наконец то ты пришел!"(с)

    Ответы: (9) (11)
  9. 29.03.2015 15:21:25 отредактировано ЗлобнийМальчик

    update:
    с вебсервисами разобрался (более менее), теперь только один вопрос - есть ли какая то возможность изменять заголовки запроса (добавлять свои поля) при использовании одинэсовских вебсервисов или лучше пихать параметры ключ/SDA 512 хэш ключа в определение каждого веб сервиса?

  10. (7) - ну я его сейчас и пишу. А я что, самоубийца, находить работу, где нужно копаться в говне WCF/SOAP/XDTO/.. и прочей [...]?

  11. ЗлобнийМальчик и воспользовался банальным кодом типа такого

    только хотел предложить подобное :)

  12. (7) ну, какое-то зерно в (6) есть.
    просто "на вкус и цвет все фломастеры разные" ©

или зарегистрируйтесь чтобы ответить!