我有以下xsd片段:
<xs:element name="MESSAGE">
<xs:complexType>
<xs:sequence>
<xs:element ref="HEADER"/>
<xs:element ref="BODY" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
<xs:attribute name="VERSION" type="xs:unsignedInt" use="required"/>
</xs:complexType>
</xs:element>
...
<xs:element name="BODY">
<xs:complexType>
<xs:choice maxOccurs="2">
<xs:element ref="LANE" minOccurs="0" maxOccurs="1"/>
<xs:element ref="DEVICE" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="TRIP" minOccurs="0" maxOccurs="1"/>
<xs:element ref="CASH_DISPOSAL" minOccurs="0" maxOccurs="1"/>
<xs:element ref="ISSUE" minOccurs="0" maxOccurs="1"/>
<xs:element ref="SHIFT" minOccurs="0" maxOccurs="1"/>
<xs:element ref="SALE_RECHARGE" minOccurs="0" maxOccurs="1"/>
<xs:element ref="LIFE" minOccurs="0" maxOc`enter code here`curs="1"/>
<xs:element ref="OBSERVATION" minOccurs="0" maxOccurs="1"/>
<xs:element ref="SURVEY_RESPONSE" minOccurs="0" maxOccurs="1"/>
<xs:element ref="BLOCK_USER" minOccurs="0" maxOccurs="1"/>
<xs:element ref="ACTION" minOccurs="0" maxOccurs="1"/>
<xs:element ref="SPECIALACTION" minOccurs="0" maxOccurs="1"/>
<xs:element ref="TEXT" minOccurs="0" maxOccurs="1"/>
<xs:element ref="RESEND" minOccurs="0" maxOccurs="1"/>
<xs:element ref="TRIP_RESEND" minOccurs="0" maxOccurs="1"/>
<xs:element ref="DISPLAY" minOccurs="0" maxOccurs="1"/>
<xs:element ref="DEBT_CANCELLATION" minOccurs="0"/>
</xs:choice>
</xs:complexType>
</xs:element>
...
这是由gsoap生成的soapStub:
#ifndef SOAP_TYPE_union_BODY
#define SOAP_TYPE_union_BODY (88)
/* union serializable only when used as a member of a struct or class with a union variant selector */
union union_BODY
{
#define SOAP_UNION_union_BODY_LANE_ (1) /**< union variant selector value for member LANE_ */
LANE *LANE_;
#define SOAP_UNION_union_BODY_DEVICE_ (2) /**< union variant selector value for member DEVICE_ */
std::vector<std::shared_ptr<DEVICE> > *DEVICE_;
#define SOAP_UNION_union_BODY_TRIP_ (3) /**< union variant selector value for member TRIP_ */
TRIP *TRIP_;
#define SOAP_UNION_union_BODY_CASH_USCOREDISPOSAL_ (4) /**< union variant selector value for member CASH_USCOREDISPOSAL_ */
CASH_USCOREDISPOSAL *CASH_USCOREDISPOSAL_;
#define SOAP_UNION_union_BODY_ISSUE_ (5) /**< union variant selector value for member ISSUE_ */
ISSUE *ISSUE_;
#define SOAP_UNION_union_BODY_SHIFT_ (6) /**< union variant selector value for member SHIFT_ */
SHIFT *SHIFT_;
#define SOAP_UNION_union_BODY_SALE_USCORERECHARGE_ (7) /**< union variant selector value for member SALE_USCORERECHARGE_ */
SALE_USCORERECHARGE *SALE_USCORERECHARGE_;
#define SOAP_UNION_union_BODY_LIFE_ (8) /**< union variant selector value for member LIFE_ */
LIFE *LIFE_;
#define SOAP_UNION_union_BODY_OBSERVATION_ (9) /**< union variant selector value for member OBSERVATION_ */
OBSERVATION *OBSERVATION_;
#define SOAP_UNION_union_BODY_SURVEY_USCORERESPONSE_ (10) /**< union variant selector value for member SURVEY_USCORERESPONSE_ */
SURVEY_USCORERESPONSE *SURVEY_USCORERESPONSE_;
#define SOAP_UNION_union_BODY_BLOCK_USCOREUSER_ (11) /**< union variant selector value for member BLOCK_USCOREUSER_ */
BLOCK_USCOREUSER *BLOCK_USCOREUSER_;
#define SOAP_UNION_union_BODY_ACTION_ (12) /**< union variant selector value for member ACTION_ */
ACTION *ACTION_;
#define SOAP_UNION_union_BODY_SPECIALACTION_ (13) /**< union variant selector value for member SPECIALACTION_ */
SPECIALACTION *SPECIALACTION_;
#define SOAP_UNION_union_BODY_TEXT_ (14) /**< union variant selector value for member TEXT_ */
TEXT *TEXT_;
#define SOAP_UNION_union_BODY_RESEND_ (15) /**< union variant selector value for member RESEND_ */
RESEND *RESEND_;
#define SOAP_UNION_union_BODY_TRIP_USCORERESEND_ (16) /**< union variant selector value for member TRIP_USCORERESEND_ */
TRIP_USCORERESEND *TRIP_USCORERESEND_;
#define SOAP_UNION_union_BODY_DISPLAY_ (17) /**< union variant selector value for member DISPLAY_ */
DISPLAY *DISPLAY_;
#define SOAP_UNION_union_BODY_DEBT_USCORECANCELLATION_ (18) /**< union variant selector value for member DEBT_USCORECANCELLATION_ */
DEBT_USCORECANCELLATION *DEBT_USCORECANCELLATION_;
};
#endif
/* D:\dd\projects\Deoban\source\Actros\developed\libs\upperLevelInterface\sep\messages.h:422 */
#ifndef SOAP_TYPE__union_BODY
#define SOAP_TYPE__union_BODY (67)
/* Choice: */
class SOAP_CMAC _union_BODY {
public:
/// Union with union union_BODY variant selector __union_BODY set to one of: SOAP_UNION_union_BODY_LANE_ SOAP_UNION_union_BODY_DEVICE_ SOAP_UNION_union_BODY_TRIP_ SOAP_UNION_union_BODY_CASH_USCOREDISPOSAL_ SOAP_UNION_union_BODY_ISSUE_ SOAP_UNION_union_BODY_SHIFT_ SOAP_UNION_union_BODY_SALE_USCORERECHARGE_ SOAP_UNION_union_BODY_LIFE_ SOAP_UNION_union_BODY_OBSERVATION_ SOAP_UNION_union_BODY_SURVEY_USCORERESPONSE_ SOAP_UNION_union_BODY_BLOCK_USCOREUSER_ SOAP_UNION_union_BODY_ACTION_ SOAP_UNION_union_BODY_SPECIALACTION_ SOAP_UNION_union_BODY_TEXT_ SOAP_UNION_union_BODY_RESEND_ SOAP_UNION_union_BODY_TRIP_USCORERESEND_ SOAP_UNION_union_BODY_DISPLAY_ SOAP_UNION_union_BODY_DEBT_USCORECANCELLATION_
int __union_BODY;
union union_BODY _BODY;
public:
/// Return unique type id SOAP_TYPE__union_BODY
virtual int soap_type(void) const { return SOAP_TYPE__union_BODY; }
/// (Re)set members to default values
virtual void soap_default(struct soap*);
/// Serialize object to prepare for SOAP 1.1/1.2 encoded output (or with SOAP_XML_GRAPH) by analyzing its (cyclic) structures
virtual void soap_serialize(struct soap*) const;
/// Output object in XML, compliant with SOAP 1.1 encoding style, return error code or SOAP_OK
virtual int soap_put(struct soap*, const char *tag, const char *type) const;
/// Output object in XML, with tag and optional id attribute and xsi:type, return error code or SOAP_OK
virtual int soap_out(struct soap*, const char *tag, int id, const char *type) const;
/// Get object from XML, compliant with SOAP 1.1 encoding style, return pointer to object or NULL on error
virtual void *soap_get(struct soap*, const char *tag, const char *type);
/// Get object from XML, with matching tag and type (NULL matches any tag and type), return pointer to object or NULL on error
virtual void *soap_in(struct soap*, const char *tag, const char *type);
/// Return a new object of type _union_BODY, default initialized and not managed by a soap context
virtual _union_BODY *soap_alloc(void) const { return SOAP_NEW(_union_BODY); }
public:
/// Constructor with initializations
_union_BODY()
{
__union_BODY = 0;
}
virtual ~_union_BODY() { }
/// Friend allocator used by soap_new__union_BODY(struct soap*, int)
friend SOAP_FMAC1 _union_BODY * SOAP_FMAC2 soap_instantiate__union_BODY(struct soap*, int, const char*, const char*, size_t*);
};
#endif
/* D:\dd\projects\Deoban\source\Actros\developed\libs\upperLevelInterface\sep\messages.h:170 */
#ifndef SOAP_TYPE_BODY
#define SOAP_TYPE_BODY (21)
/* complex XSD type 'BODY': */
class SOAP_CMAC BODY {
public:
/// Sequence of 0 to 2 elements 'BODY' of XSD type 'union-BODY' stored in dynamic array _BODY of length __size_BODY
int __size_BODY;
_union_BODY *_BODY;
/// Context that manages this object
struct soap *soap;
public:
/// Return unique type id SOAP_TYPE_BODY
virtual int soap_type(void) const { return SOAP_TYPE_BODY; }
/// (Re)set members to default values
virtual void soap_default(struct soap*);
/// Serialize object to prepare for SOAP 1.1/1.2 encoded output (or with SOAP_XML_GRAPH) by analyzing its (cyclic) structures
virtual void soap_serialize(struct soap*) const;
/// Output object in XML, compliant with SOAP 1.1 encoding style, return error code or SOAP_OK
virtual int soap_put(struct soap*, const char *tag, const char *type) const;
/// Output object in XML, with tag and optional id attribute and xsi:type, return error code or SOAP_OK
virtual int soap_out(struct soap*, const char *tag, int id, const char *type) const;
/// Get object from XML, compliant with SOAP 1.1 encoding style, return pointer to object or NULL on error
virtual void *soap_get(struct soap*, const char *tag, const char *type);
/// Get object from XML, with matching tag and type (NULL matches any tag and type), return pointer to object or NULL on error
virtual void *soap_in(struct soap*, const char *tag, const char *type);
/// Return a new object of type BODY, default initialized and not managed by a soap context
virtual BODY *soap_alloc(void) const { return SOAP_NEW(BODY); }
public:
/// Constructor with initializations
BODY()
{
__size_BODY = 0;
_BODY = NULL;
soap = (struct soap *)0;
}
virtual ~BODY() { }
/// Friend allocator used by soap_new_BODY(struct soap*, int)
friend SOAP_FMAC1 BODY * SOAP_FMAC2 soap_instantiate_BODY(struct soap*, int, const char*, const char*, size_t*);
};
#endif
我构建了如下消息:
MESSAGE soapMSG;
HEADER soapHeader;
BODY soapBody;
LANE soapLane;
...
soapMSG.BODY_ = std::make_shared<BODY>(); // here i use a maping pointer to sharedptr
soapMSG.BODY_->_BODY = new ((_union_BODY *)soap_malloc(ctx, 2 * sizeof(_unionBody))) _union_BODY[2];
soapMSG.BODY_->__size_BODY = 2;
soapMSG.BODY_->_BODY[0].__union_BODY = SOAP_UNION_union_BODY_LANE_;
soapMSG.BODY_->_BODY[0]._BODY.LANE_ = &soapLane;
...
问题是: 当xsd包含xs:choice时,gsoap会生成一个通过动态数组使用的联合,问题是每个_union_Body gsoap都会使用包含的父元素呈现它
<MESSAGE xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" VERSION="0">
<HEADER SOCIETY="0" CONCESSION="0" FROM="456" TO="123" DATETIME="1970-01-01 01:00:00" SEQUENCE="0" CODE="8" LOCAL="0" MAINTENANCE="0" CHECKSUM="">
</HEADER>
<BODY>
<BODY>
<LANE STATUS="0" COLLECTOR="" SHIFT_NUMBER="0" BEGIN_DATETIME="2017-10-19 10:04:58" FUNCTION="1" WORK_MODE="2"></LANE>
</BODY>
...
</BODY>
</MESSAGE>
我该如何避免这种情况?
提前谢谢!!
答案 0 :(得分:0)
我找到了解决方案: 来自Genivia Doc “ 成员成为隐藏的XML元素,即当其名称以双下划线开头时,不会以XML格式呈现。这使得对数据成员集合进行排序成为可能,基本上通过形成一系列可以选择或重复的元素。“ 然后我修改了gsoap从
生成的.h/// @brief Top-level root element "":BODY
/// @brief "":BODY is a complexType.
///
/// class BODY operations:
/// - BODY* soap_new_BODY(soap*) allocate and default initialize
/// - BODY* soap_new_BODY(soap*, int num) allocate array and default initialize values
/// - BODY* soap_new_req_BODY(soap*, ...) allocate, set required members
/// - BODY* soap_new_set_BODY(soap*, ...) allocate, set all public members
/// - BODY::soap_default(soap*) default initialize members
/// - int soap_read_BODY(soap*, BODY*) deserialize from a stream
/// - int soap_write_BODY(soap*, BODY*) serialize to a stream
/// - BODY* BODY::soap_dup(soap*) returns deep copy of BODY, copies the (cyclic) graph structure when a context is provided, or (cycle-pruned) tree structure with soap_set_mode(soap, SOAP_XML_TREE) (use soapcpp2 -Ec)
/// - BODY::soap_del() deep deletes BODY data members, use only after BODY::soap_dup(NULL) (use soapcpp2 -Ed)
class BODY
{ public:
// BEGIN CHOICE <xs:choice maxOccurs="2">
$int __size_BODY 0:2;
class ___union_BODY
{
$int __union_BODY ; ///< Union union_BODY selector: set to SOAP_UNION_union_BODY_<fieldname>
/// Union for choice in BODY.
union union_BODY
{
/// Element reference ":""":LANE.
LANE* LANE_ 0; ///< Optional element.
/// Vector of std::shared_ptr<DEVICE> element refs of length 0..unbounded.
std::vector<std::shared_ptr<DEVICE> > *DEVICE_ 0;
/// Element reference ":""":TRIP.
TRIP* TRIP_ 0; ///< Optional element.
/// Element reference ":""":CASH_DISPOSAL.
CASH_USCOREDISPOSAL* CASH_USCOREDISPOSAL_ 0; ///< Optional element.
/// Element reference ":""":ISSUE.
ISSUE* ISSUE_ 0; ///< Optional element.
/// Element reference ":""":SHIFT.
SHIFT* SHIFT_ 0; ///< Optional element.
/// Element reference ":""":SALE_RECHARGE.
SALE_USCORERECHARGE* SALE_USCORERECHARGE_ 0; ///< Optional element.
/// Element reference ":""":LIFE.
LIFE* LIFE_ 0; ///< Optional element.
/// Element reference ":""":OBSERVATION.
OBSERVATION* OBSERVATION_ 0; ///< Optional element.
/// Element reference ":""":SURVEY_RESPONSE.
SURVEY_USCORERESPONSE* SURVEY_USCORERESPONSE_ 0; ///< Optional element.
/// Element reference ":""":BLOCK_USER.
BLOCK_USCOREUSER* BLOCK_USCOREUSER_ 0; ///< Optional element.
/// Element reference ":""":ACTION.
ACTION* ACTION_ 0; ///< Optional element.
/// Element reference ":""":SPECIALACTION.
SPECIALACTION* SPECIALACTION_ 0; ///< Optional element.
/// Element reference ":""":TEXT.
TEXT* TEXT_ 0; ///< Optional element.
/// Element reference ":""":RESEND.
RESEND* RESEND_ 0; ///< Optional element.
/// Element reference ":""":TRIP_RESEND.
TRIP_USCORERESEND* TRIP_USCORERESEND_ 0; ///< Optional element.
/// Element reference ":""":DISPLAY.
DISPLAY* DISPLAY_ 0; ///< Optional element.
/// Element reference ":""":DEBT_CANCELLATION.
DEBT_USCORECANCELLATION* DEBT_USCORECANCELLATION_ 0; ///< Optional element.
} _BODY ;
} *___BODY ;
// END OF CHOICE
/// A handle to the soap struct context that manages this instance when instantiated by a context or NULL otherwise (automatically set).
struct soap *soap ;
};
为:
let arr1 = [
{ id: "abdc4051", date: "2017-01-24" },
{ id: "abdc4052", date: "2017-01-22" }
];
let arr2 = [
{ id: "abdc4051", name: "ab" },
{ id: "abdc4052", name: "abc" }
];
let arr3 = [];
arr1.forEach((itm, i) => {
arr3.push(Object.assign({}, itm, arr2[i]));
});
console.log(arr3);
请注意我已将类_unionody_BODY重命名为___unión_BODY,并将变量名_BODY重命名为___ BODY
非常感谢你。