2011-08-15 50 views
4

如果我寫此SOAP::Data::Builder代碼(其中$sb是SOAP ::數據::生成器對象)SOAP ::數據::生成器,除去的xsi:無= 「真」,當沒有設置值

$sb->add_elem(
     attributes => { run => 'true' }, 
     name  => 'ccAuthService', 
#  value  => ' ', # hack to prevent cs side unparseable xml 
    ); 

它會生成以下內容

<ccAuthService xsi:nil="true" run="true" /> 

這是不可接受的,因爲xsi:nil會在接收端造成問題。但是,如果我取消註釋掉的註釋行,我得到

<ccAuthService run="true"> </ccAuthService> 

從技術上講,這是有效的,所以這是一種解決方法。但我最終想要的是

<ccAuthService run="true" /> 

我知道的工作,我只是不知道如何讓它產生。

回答

0

您可以按原樣將SOAP生成保留在SOAP中,在發送端解析使用解析器生成的代碼(如XML::Twig),並使用相同的庫打印出來,應用所需的選項以便在接收端。

+0

聽起來比我現在的解決方法差10倍。我寧願發一個''到處理器。 – xenoterracide

+0

對我來說,聽起來好幾百倍,因爲您不必依靠黑客和特定於實現的「解決方法」。 –

+0

你不知道我已經有多少解決方法......接收端沒有使用理智解析......這增加了一層複雜性,並要求我重寫。 – xenoterracide

1

$ sb將您的元素和餵食它通過xslt處理器生成SOAP消息。 你可以在這個過程中插入'中間人'的邏輯嗎?

在我的情況下,我使用wsdl生成一個.Net 4 C#SoapHttpClientProtocol對象,該對象具有一個可以覆蓋的虛擬方法GetWriterForMessage。此方法返回用於寫出SOAP消息的XmlWriter對象(本質上是xslt處理器)。我能夠創建一個自定義的XmlWriter,它忽略了「本地名稱爲nil」命令的「寫出來的屬性」。

這個解決方案的好處是它是通用的。所以,現在它是我的庫的一部分,只要我想過濾任何Xml輸出就可以使用它。它只需要一個自定義類。

看起來你的代碼是c?也許$ sb有一個指針可以設置爲將其'xml writer'重定向到一個自定義方法。

希望這可以幫助別人。

0

我也有同樣的問題,這就是我如何解決它,也許它也可以幫助別人。

如果soap數據對象的值爲undef,則設置'xsi:nil = true',將其設置爲arrayref以解決問題。

請參見下面的代碼以供參考:

皁格式:

< m:clHotelIdInfo>< m:HotelIdInfo xsi:nil=true id="1219615" />< /m:clHotelIdInfo> 

SOAP對象結構

*bless({ 
    '_name' => 'clHotelIdInfo', 
    '_signature' => [], 
    '_value' => [ 
        \bless({ 
           '_signature' => [], 
           '_value' => [ 
              bless({ 
                '_name' => 'HotelIdInfo', 
                '_signature' => [], 
                **'_value' => [ 
                    undef 
                   ],** 
                '_prefix' => 'm', 
                '_attr' => { 
                    'id' => '1219615' 
                   } 
                }, 'SOAP::Data') 
              ], 
           '_attr' => {} 
          }, 'SOAP::Data') 
       ], 
    '_prefix' => 'm', 
    '_attr' => {} 
}, 'SOAP::Data')* 

預計皁格式:

< m:clHotelIdInfo>< m:HotelIdInfo id="1219615" /></ m:clHotelIdInfo>               

所以肥皂的OBJ ECT結構必須是:

*bless({ 
     '_name' => 'clHotelIdInfo', 
     '_signature' => [], 
     '_value' => [ 
         \bless({ 
            '_signature' => [], 
            '_value' => [ 
               bless({ 
                 '_name' => 'HotelIdInfo', 
                 '_signature' => [], 
                 **'_value' => [],** 
                 '_prefix' => 'm', 
                 '_attr' => { 
                     'id' => '1219615' 
                    } 
                 }, 'SOAP::Data') 
               ], 
            '_attr' => {} 
           }, 'SOAP::Data') 
        ], 
     '_prefix' => 'm', 
     '_attr' => {} 
}, 'SOAP::Data')* 

如果你觀察對象HotelIdInfo精心價值是民主基金較早,其變更爲數組引用的時候,幫我擺脫「XSI:無=真」。

我不必更改cpan的任何現有模塊。只需設置值arrayref而不是undef。這是perl語言的解決方案。

2

這是一個用SOAP :: Lite(SOAP :: Data :: Builder使用)修復此問題的解決方案。

定義某處在你的代碼如下:

sub SOAP::Serializer::as_nonil 
{ 
    my ($self, $value, $name, $type, $attr) = @_; 
    delete $attr->{'xsi:nil'}; 
    return [ $name, $attr, $value ]; 
} 

要使用此類型:

SOAP::Data->new(
    type => 'nonil', 
    name => 'ping', 
    prefix => '', 
    uri => 'http://myschema.domain/', 
); 

一些這方面的提示是在SOAP::Serializer