首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有OPC DA添加属性的gSOAP

具有OPC DA添加属性的gSOAP
EN

Stack Overflow用户
提问于 2012-06-27 21:31:26
回答 2查看 1.9K关注 0票数 2

我正在尝试开发一个soap客户机,它将通过OPC DA规范访问数据:Here

我已经使用了gSOAP提供的工具从OPC Foundations生成gSOAP头文件。(相关部分如下)

我似乎无法让gSOAP正确地将属性添加到标记中。(参见下面的输出部分)。有没有内置的方法可以做到这一点,或者需要修改WSDL/gSOAP头?

WSDL摘录:

代码语言:javascript
复制
<s:complexType name="ItemValue">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="DiagnosticInfo" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Value" />
<s:element minOccurs="0" maxOccurs="1" name="Quality" type="s0:OPCQuality" />
</s:sequence>
<s:attribute name="ValueTypeQualifier" type="s:QName" />
<s:attribute name="ItemPath" type="s:string" />
<s:attribute name="ItemName" type="s:string" />
<s:attribute name="ClientItemHandle" type="s:string" />
<s:attribute name="Timestamp" type="s:dateTime" />
<s:attribute name="ResultID" type="s:QName" />
</s:complexType>

生成的gSOAP报头

代码语言:javascript
复制
class ns1__ItemValue
{ public:
/// Element DiagnosticInfo of type xs:string.
    char*                                DiagnosticInfo                 0;  ///< Optional element.
/// Element 'Value' has no type or ref: assuming XML content.
    _XML                                 Value                          0;  ///< Optional element.
/// Element Quality of type "http://opcfoundation.org/webservices/XMLDA/1.0/":OPCQuality.
    ns1__OPCQuality*                     Quality                        0;  ///< Optional element.
/// Attribute ValueTypeQualifier of type xs:QName.
   @_QName                               ValueTypeQualifier             0;  ///< Optional attribute.
/// Attribute ItemPath of type xs:string.
   @char*                                ItemPath                       0;  ///< Optional attribute.
/// Attribute ItemName of type xs:string.
   @char*                                ItemName                       0;  ///< Optional attribute.
/// Attribute ClientItemHandle of type xs:string.
   @char*                                ClientItemHandle               0;  ///< Optional attribute.
/// Attribute Timestamp of type xs:dateTime.
   @time_t*                              Timestamp                      0;  ///< Optional attribute.
/// Attribute ResultID of type xs:QName.
   @_QName                               ResultID                       0;  ///< Optional attribute.
/// A handle to the soap struct that manages this instance (automatically set)
    struct soap                         *soap                          ;
};

生成的代码

代码语言:javascript
复制
class SOAP_CMAC ns1__ItemValue
{
public:
    char *DiagnosticInfo;   /* optional element of type xsd:string */
    char *Value;    /* optional element of type xsd:anyType */
    class ns1__OPCQuality *Quality; /* optional element of type ns1:OPCQuality */
    char *ValueTypeQualifier;   /* optional attribute */
    char *ItemPath; /* optional attribute */
    char *ItemName; /* optional attribute */
    char *ClientItemHandle; /* optional attribute */
    time_t *Timestamp;  /* optional attribute */
    char *ResultID; /* optional attribute */
    struct soap *soap;  /* transient */
public:
    virtual int soap_type() const { return 18; } /* = unique id SOAP_TYPE_ns1__ItemValue */
    virtual void soap_default(struct soap*);
    virtual void soap_serialize(struct soap*) const;
    virtual int soap_put(struct soap*, const char*, const char*) const;
    virtual int soap_out(struct soap*, const char*, int, const char*) const;
    virtual void *soap_get(struct soap*, const char*, const char*);
    virtual void *soap_in(struct soap*, const char*, const char*);
             ns1__ItemValue() : DiagnosticInfo(NULL), Value(NULL), Quality(NULL), ValueTypeQualifier(NULL), ItemPath(NULL), ItemName(NULL), ClientItemHandle(NULL), Timestamp(NULL), ResultID(NULL), soap(NULL) { }
    virtual ~ns1__ItemValue() { }
};

输出

代码语言:javascript
复制
<ns1:Items
    ClientItemHandle="Channel1.Device1"
    ItemName="Channel_1.Device_1.Tag_1"
    ValueTypeQualifier="xsd:unsignedInt">
    <Value
        xmlns="http://opcfoundation.org/webservices/XMLDA/1.0/">
        5
    </Value>
</ns1:Items>

所需的输出

代码语言:javascript
复制
<ns1:Items
    ClientItemHandle="Channel1.Device1"
    ItemName="Channel_1.Device_1.Tag_1"
    ValueTypeQualifier="xsd:unsignedInt">
    <Value
        xmlns="http://opcfoundation.org/webservices/XMLDA/1.0/"
        xsi:Type="xsd:unsignedInt">
        5
    </Value>
</ns1:Items>

输出是指生成并通过网络发送到远程服务器的XML。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-28 22:58:13

@Tisho,感谢您的投入。

事实证明,OPC Foundation提供的WSDL缺少在value元素上指定类型。我们的解决方案是添加一个s:anyType类型,这允许我们使用多态类型,例如:

xsd_unsignedInt

xsd_string

xsd__anyType

由于所有类型都继承自xsd__anyType,并且包含了一个虚拟soap_type函数,因此我们可以使用任何类型,并将它们存储在值中,然后gSOAP神奇地使用soap_type来确定变量是什么类型。

修改了OPC Foundation的WSDL的相关部分:

代码语言:javascript
复制
<s:complexType name="ItemValue">
  <s:sequence>
    <s:element minOccurs="0" maxOccurs="1" name="DiagnosticInfo" type="s:string"/>
    <s:element minOccurs="0" maxOccurs="1" name="Value" type="s:anyType"/> <!-- Here -->
    <s:element minOccurs="0" maxOccurs="1" name="Quality" type="s0:OPCQuality"/>
  </s:sequence>
  <s:attribute name="ValueTypeQualifier" type="s:QName"/>
  <s:attribute name="ItemPath" type="s:string"/>
  <s:attribute name="ItemName" type="s:string"/>
  <s:attribute name="ClientItemHandle" type="s:string"/>
  <s:attribute name="Timestamp" type="s:dateTime"/>
  <s:attribute name="ResultID" type="s:QName"/>
</s:complexType>

下面是新的gSOAP生成的头文件

代码语言:javascript
复制
class ns1__ItemValue : public xsd__anyType
{ public:
/// Element DiagnosticInfo of type xs:string.
    char*                                DiagnosticInfo                 0;  ///< Optional element.
/// Element Value of type xs:anyType.
    xsd__anyType*                        Value                          0;  ///< Optional element.
/// Element Quality of type "http://opcfoundation.org/webservices/XMLDA/1.0/":OPCQuality.
    ns1__OPCQuality*                     Quality                        0;  ///< Optional element.
/// Attribute ValueTypeQualifier of type xs:QName.
   @_QName                               ValueTypeQualifier             0;  ///< Optional attribute.
/// Attribute ItemPath of type xs:string.
   @char*                                ItemPath                       0;  ///< Optional attribute.
/// Attribute ItemName of type xs:string.
   @char*                                ItemName                       0;  ///< Optional attribute.
/// Attribute ClientItemHandle of type xs:string.
   @char*                                ClientItemHandle               0;  ///< Optional attribute.
/// Attribute Timestamp of type xs:dateTime.
   @time_t*                              Timestamp                      0;  ///< Optional attribute.
/// Attribute ResultID of type xs:QName.
   @_QName                               ResultID                       0;  ///< Optional attribute.
};
票数 1
EN

Stack Overflow用户

发布于 2012-06-28 02:55:26

这里有一些可能会有帮助的东西。我现在不能测试它,所以它只是一个建议。看看“空指针”:http://www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc11.9

代码语言:javascript
复制
struct myStruct 
{ 
   int __type; // the SOAP_TYPE pointed to by p 
   void *p; 
};

据我从文档中了解,这是用来序列化任何东西的,并指定它的类型。因此,用这个结构替换Value元素的_XML类型可能是可行的。然后,您只需使用相应的值设置__type属性:

代码语言:javascript
复制
struct ns1_Value {
   int __type; // the SOAP_TYPE pointed to by p 
   void *p; 
}
struct ns1_Value value; 
int n; 
value.p = &n; 
value.__type = SOAP_TYPE_int; 

解决这个问题的另一种方法是序列化原始xml而不是元素……或者考虑一些xs:元素,它扩展了xs:anyType,但定义了xs:type..实际上,gSoap是一个很酷的产品,但要充分利用它,你需要学习如何破解它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11227404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档