2016-10-12 37 views
2

我知道這是一個非常古老的Perl模塊(自上次更新5年前)。我發現它對我正在做的一個項目很有用,它需要在Perl中。而不是從底層開始,我發現這對於做基礎很有幫助。我已經固定了這幾個錯誤 - 但是這一個我無法弄清楚Net :: Kashflow - 不能使用utf8描述

有問題的模塊是:https://github.com/simoncozens/Net-KashFlow

這個問題的一個例子用法是:

my $kf = Net::KashFlow->new(username => q|[email protected]|, password => "xxxx"); 

my $i = $kf->create_invoice({ 
    CustomerReference => "0123-1111111", CustomerID => 50108952, 
    CurrencyCode => "EUR" 
}) || die $!; 


$i->add_line({ 
    Quantity => 1, 
    Description => "íéó foo bar test", 
    Rate => 10, 
    VatAmount => 4, 
    VatRate => 0, 
    CurrencyCode => "GBP" 
}); 

此產品被添加,但 「描述」 值被轉換爲:

7enzIGZvbyBiYXIgdGVzdA ==

如果您使用正常的a-z 0-9,它工作正常(並正確顯示)。這個問題似乎是它編碼成base64,然後在另一端沒有被正確解碼。我的猜測是KashFlow不會「修復」這個,所以它真的需要這樣做。我並不十分熟悉SOAP :: Lite模塊(再次看來,它是一個相當老的模塊!),但它就是這樣使用的。

這是我認爲的一部分涉及增加一個新的「線」,以發票:

InsertInvoiceLine => { 
    endpoint => 'https://securedwebapp.com/api/service.asmx', 
    soapaction => 'KashFlow/InsertInvoiceLine', 
    namespace => 'KashFlow', 
    parameters => [ 
     SOAP::Data->new(name => 'UserName', type => 'xsd:string', attr => {}), 
     SOAP::Data->new(name => 'Password', type => 'xsd:string', attr => {}), 
     SOAP::Data->new(name => 'InvoiceID', type => 'xsd:int', attr => {}), 
     SOAP::Data->new(name => 'InvLine', type => 'tns:InvoiceLine', attr => {}),=> {}) 
    ], # end parameters 
    }, # end InsertInvoiceLine 

你可以看到這裏的結構:

https://securedwebapp.com/api/service.asmx?op=InsertInvoiceLine

研究此之後,有人建議你告訴SOAP :: Lite不是使用(我假設)將utf8轉換爲base64,如下所示:

結構爲:

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
    <InsertInvoiceLine xmlns="KashFlow"> 
     <UserName>string</UserName> 
     <Password>string</Password> 
     <InvoiceID>int</InvoiceID> 
     <InvLine> 
     <Quantity>decimal</Quantity> 
     <Description>string</Description> 
     <Rate>decimal</Rate> 
     <ChargeType>int</ChargeType> 
     <VatRate>decimal</VatRate> 
     <VatAmount>decimal</VatAmount> 
     <ProductID>int</ProductID> 
     <Sort>int</Sort> 
     <ProjID>int</ProjID> 
     <LineID>int</LineID> 
     <ValuesInCurrency>integer</ValuesInCurrency> 
     </InvLine> 
    </InsertInvoiceLine> 
    </soap:Body> 
</soap:Envelope> 

所以看起來像它身體> InsertInvoiceLine> InvLine>描述 ..但我不確定我怎麼能告訴它不特定的字符串編碼。

任何意見將不勝感激。雖然它不是一個主要的展示瓶塞(因爲所有數據都在系統中),但如果預期的項目名稱會更好或更容易:)

謝謝!

回答

2

我認爲這可能是SOAP::Lite當它認爲它們不是ASCII的特定子集時決定將其轉換爲base64。你會在SOAP::Serializer發現這個啓發式在SOAP/Lite.pm

$self->typelookup({ 
     'base64Binary' => 
      [10, sub {$_[0] =~ /[^\x09\x0a\x0d\x20-\x7f]/ }, 'as_base64Binary'], 
     'zerostring' => 
      [12, sub { $_[0] =~ /^0\d+$/ }, 'as_string'], 

... many other types ... 
     'string' => 
      [100, sub {1}, 'as_string'], 
    }); 

此進場時,SOAP ::精簡版不知道對象的類型,因爲沒有人告訴它。我猜你的程序中它的序列號是Descriptiontypelookup粘髒手套。

從這裏你是你自己的,因爲SOAP :: Lite沒有趣味。我會先從SOAP :: Lite入手,看看你可以跟蹤什麼。複製SOAP/Lite。pm某處存檔,並將該位置放入您的@INC。這樣你就不會搞亂原始文件。

如果您不希望以base64,這可能是因爲在刪除該線typelookup那樣簡單,雖然聲明Description型會更合適(工作也是兔子的洞,潛在的)。快速修復功能可以在您修復正確的修復程序時發揮作用。

還有Perlmonk的冥想How to convince SOAP::Lite to return UTF-8 data in responses as UTF-8?

+0

感謝您的回覆Brian。我有一種感覺,這不會很簡單。我想我只是要替換「正常」的角色:'tr {ÀÄÄÄÄÄÄÄÈÈÇÇÊÈËéêèëÏÌÎïìîÖÔÒöôòÜÛÙüûù} {AAAaaaCcEEEEeeeeIIIiiiOOOoooUUUuuu};'。這只是我自己的後端發票系統,所以它不一定具有適當的口音 –