在测试中,客户端请求一个xml文档(该文档存放于oracle数据库中,CLOB型),发现有时候能正常取到,有时候取到的数据以xml方式解析解析不了。
而我使用java客户端来请求该数据时,又能正常得到所有xml数据,和库中一样。为了彻底解决这个问题,写了一个测试的webservice接口。
- public class TestService {
- public TestService() {
- }
- public String getMessage() {
- return message;
- }
- }
这里的message其实是一个xml文档(由于不能贴在里,会丢信息原来信息无法阅读,所以在后面贴出)。
若message赋值为xml_a时,delphi客户端没有任何问题,能得到正常结果。xml_a内容如下:
- String xml_a =
- "<xml version=\"1.0\" encoding=\"UTF-8\"?>"
- + " <bCCH_BCH_Message>xxyyzz"
- + " <message>"
- + " <sfn_Prime>25sfn_Prime>"
- + " <payload>"
- + " <completeSIB_List>"
- + " <element>"
- + " <sib_Type>systemInformationBlockType7sib_Type>"
- + " <sib_Data_variable>01 80 80sib_Data_variable>"
- + " element>"
- + " <element>"
- + " <sib_Type>schedulingBlock1sib_Type>"
- + " <sib_Data_fixed>08 0D B0 1D 05 80 C4 4C 06 A0sib_Data_fixed>"
- + " element>"
- + " completeSIB_List>"
- + " payload>"
- + " message>"
- + " <xxyyzz1>xxyyzz123xxyyzz1>"
- + " <xxyyzz1>xxyyzz987xxyyzz1>"
- + " bCCH_BCH_Message>";
用tcptrace工具得到的返回结果,<写为<,>为>,&为&,这是由于是传输的数据就是以XML,在这个xml文档内再包含其他xml内容时需要转义。
当xml_b(比较长)赋值给message时,如下:
- String xml_b =
- "xml version=\"1.0\" encoding=\"UTF-8\"?>"
- + "<uL_DCCH_Message> "
- + "<xyz>"
- +" <a>1a>"
- +" <b>2b>"
- +" <c>3c>"
- +" <d>4d>"
- +" <e>5e>"
- +" <f>6f>"
- +" <g>7g>"
- +" <h>8h>"
- +" <i>9i>"
- +" <j>10j>"
- +" <k>11k>"
- +" <l>12l>"
- +" <m>13m>"
- +"xyz>"
- + " <message>"
- + " <rrcConnectionSetupComplete>"
- + " <rrc_TransactionIdentifier>0rrc_TransactionIdentifier>"
- + " <startList>"
- + " <element>"
- + " <cn_DomainIdentity>cs_domaincn_DomainIdentity>"
- + " <start_Value>00000000000000000100start_Value>"
- + " element>"
- + " <element>"
- + " <cn_DomainIdentity>ps_domaincn_DomainIdentity>"
- + " <start_Value>00000000000000010010start_Value>"
- + " element>"
- + " startList>"
- + " <ue_RadioAccessCapability>"
- + " <accessStratumReleaseIndicator>r99accessStratumReleaseIndicator>"
- + " <pdcp_Capability>"
- + " <losslessSRNS_RelocationSupport>falselosslessSRNS_RelocationSupport>"
- + " <supportForRfc2507>"
- + " <notSupported/>"
- + " supportForRfc2507>"
- + " pdcp_Capability>"
- + " <rlc_Capability>"
- + " <totalRLC_AM_BufferSize>kb150totalRLC_AM_BufferSize>"
- + " <maximumRLC_WindowSize>mws2047maximumRLC_WindowSize>"
- + " <maximumAM_EntityNumber>am6maximumAM_EntityNumber>"
- + " rlc_Capability>"
- + " <transportChannelCapability>"
- + " <dl_TransChCapability>"
- + " <maxNoBitsReceived>b6400maxNoBitsReceived>"
- + " <maxConvCodeBitsReceived>b6400maxConvCodeBitsReceived>"
- + " <turboDecodingSupport>"
- + " <supported>b6400supported>"
- + " turboDecodingSupport>"
- + " <maxSimultaneousTransChs>e8maxSimultaneousTransChs>"
- + " <maxSimultaneousCCTrCH_Count>1maxSimultaneousCCTrCH_Count>"
- + " <maxReceivedTransportBlocks>tb32maxReceivedTransportBlocks>"
- + " <maxNumberOfTFC>tfc128maxNumberOfTFC>"
- + " <maxNumberOfTF>tf64maxNumberOfTF>"
- + " dl_TransChCapability>"
- + " <ul_TransChCapability>"
- + " <maxNoBitsTransmitted>b6400maxNoBitsTransmitted>"
- + " <maxConvCodeBitsTransmitted>b6400maxConvCodeBitsTransmitted>"
- + " <turboEncodingSupport>"
- + " <supported>b6400supported>"
- + " turboEncodingSupport>"
- + " <maxSimultaneousTransChs>e8maxSimultaneousTransChs>"
- + " <modeSpecificInfo>"
- + " <fdd/>"
- + " modeSpecificInfo>"
- + " <maxTransmittedBlocks>tb32maxTransmittedBlocks>"
- + " <maxNumberOfTFC>tfc64maxNumberOfTFC>"
- + " <maxNumberOfTF>tf64maxNumberOfTF>"
- + " ul_TransChCapability>"
- + " transportChannelCapability>"
- + " <rf_Capability>"
- + " <fddRF_Capability>"
- + " <ue_PowerClass>3ue_PowerClass>"
- + " <txRxFrequencySeparation>mhz190txRxFrequencySeparation>"
- + " fddRF_Capability>"
- + " rf_Capability>"
- + " <physicalChannelCapability>"
- + " <fddPhysChCapability>"
- + " <downlinkPhysChCapability>"
- + " <maxNoDPCH_PDSCH_Codes>1maxNoDPCH_PDSCH_Codes>"
- + " <maxNoPhysChBitsReceived>b9600maxNoPhysChBitsReceived>"
- + " <supportForSF_512>falsesupportForSF_512>"
- + " <supportOfPDSCH>falsesupportOfPDSCH>"
- + " <simultaneousSCCPCH_DPCH_Reception>"
- + " <notSupported/>"
- + " simultaneousSCCPCH_DPCH_Reception>"
- + " downlinkPhysChCapability>"
- + " <uplinkPhysChCapability>"
- + " <maxNoDPDCH_BitsTransmitted>b9600maxNoDPDCH_BitsTransmitted>"
- + " <supportOfPCPCH>falsesupportOfPCPCH>"
- + " uplinkPhysChCapability>"
- + " fddPhysChCapability>"
- + " physicalChannelCapability>"
- + " <ue_MultiModeRAT_Capability>"
- + " <multiRAT_CapabilityList>"
- + " <supportOfGSM>falsesupportOfGSM>"
- + " <supportOfMulticarrier>falsesupportOfMulticarrier>"
- + " multiRAT_CapabilityList>"
- + " <multiModeCapability>fddmultiModeCapability>"
- + " ue_MultiModeRAT_Capability>"
- + " <securityCapability>"
- + " <cipheringAlgorithmCap>uea1 uea0cipheringAlgorithmCap>"
- + " <integrityProtectionAlgorithmCap>uia1integrityProtectionAlgorithmCap>"
- + " securityCapability>"
- + " <ue_positioning_Capability>"
- + " <standaloneLocMethodsSupported>falsestandaloneLocMethodsSupported>"
- + " <ue_BasedOTDOA_Supported>falseue_BasedOTDOA_Supported>"
- + " <networkAssistedGPS_Supported>noNetworkAssistedGPSnetworkAssistedGPS_Supported>"
- + " <supportForUE_GPS_TimingOfCellFrames>falsesupportForUE_GPS_TimingOfCellFrames>"
- + " <supportForIPDL>falsesupportForIPDL>"
- + " ue_positioning_Capability>"
- + " <measurementCapability>"
- + " <downlinkCompressedMode>"
- + " <fdd_Measurements>truefdd_Measurements>"
- + " downlinkCompressedMode>"
- + " <uplinkCompressedMode>"
- + " <fdd_Measurements>truefdd_Measurements>"
- + " uplinkCompressedMode>"
- + " measurementCapability>"
- + " ue_RadioAccessCapability>"
- + " rrcConnectionSetupComplete>"
- + " message>"
- + "uL_DCCH_Message>";
每次delphi客户端得到的结果解析不了。后用tcptrace工具截获请求和webservice返回的结果,得出结果是:实际的xml文档被夹在CDATAT标记中间,并没有(<写为<,>为>,&为&)转义。这也是delphi获得的结果,delphi对获得的串类型没有作任何处理,所以无法解析,除非去掉首尾CDATAT部分。而java的客户端可以得到的结果(去掉了CDATAT标记),即不包含CDATAT部分。问题出现在各自的SOAP引擎(根据SOAP规范生成请求应答)或消息的解析上(解析以xml传过来的数据)。
查了一下XML资料查到类似的一段:
若果XML文档中包含XML或HTML时,那么<和>和&分别写成<和>和&来转义;若包含的XML文档过长,把整个XML或HTML包在CDATA标记里,避免转义造成XML文档膨胀过大,尤其通过网络来传输的xml尤为重要。
再对照前面给出的2各XML文档,区别就是长度。若过长websphere就使用CDATA标记,若不太长则使用转义。到底多长才使用CDATA标记,没找到相关的说明。
但delphi却没有这么灵活,无法处理这种情况。我同事只好每次得到XML信息,先判断是否有CDATA标记,有就去头截尾。