none
請教 XML 反序列化的問題: System.InvalidOperationException 未定義的命名空間前置詞 RRS feed

  • 一般討論

  • 因為我在呼別人的服務, 它的xml 內容是有問題的, 導致反序列化時發生錯誤

    System.InvalidOperationException 未定義的命名空間前置詞 'axis2ns22'

    因為無法請對方修改, 必須client想辦法解決, 想請教大家有沒有什麼好的解決. (PS. .NET Framework 2.0)

    XML 內容, 可以發現 axis2ns22:date 沒有宣告. 根據trial & error的結果, 發現這個名稱空間的pattern是'axis2ns??' , ??是會動態長的.

    <?xml version="1.0" encoding="UTF-8"?>
    <XResponse xmlns:ax23="http://api.interact.unicacorp.com/xsd" xmlns:ns="http://soap.api.interact.unicacorp.com">
        <ax23:profileRecord
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:ax23="http://api.interact.unicacorp.com/xsd"
          xsi:type="ax23:XNameValuePairImpl">
          <ax23:name>eventtime</ax23:name>
          <ax23:value xsi:type="axis2ns22:date">
            <date xmlns="http://www.w3.org/2001/XMLSchema">28</date>
            <day xmlns="http://www.w3.org/2001/XMLSchema">5</day>
            <hours xmlns="http://www.w3.org/2001/XMLSchema">18</hours>
            <minutes xmlns="http://www.w3.org/2001/XMLSchema">50</minutes>
            <month xmlns="http://www.w3.org/2001/XMLSchema">8</month>
            <seconds xmlns="http://www.w3.org/2001/XMLSchema">58</seconds>
            <time xmlns="http://www.w3.org/2001/XMLSchema">1348829458186</time>
            <timezoneOffset xmlns="http://www.w3.org/2001/XMLSchema">-480</timezoneOffset>
            <year xmlns="http://www.w3.org/2001/XMLSchema">112</year>
          </ax23:value>
          <ax23:valueAsDate>2012-09-28</ax23:valueAsDate>
          <ax23:valueAsNumeric xsi:nil="true"/>
          <ax23:valueAsString xsi:nil="true"/>
          <ax23:valueDataType>datetime</ax23:valueDataType>
        </ax23:profileRecord>
     </XResponse>
    


    我的程式

    private object valueField;
    
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(IsNullable = true)]
            public object value
            {
                get
                {
                    return this.valueField;
                }
                set
                {
                    this.valueField = value;
                }
            }

    目前我只能先用 [System.Xml.Serialization.XmlIgnoreAttribute()]

    把這個區塊先忽略.

    請問有沒有什麼方法去忽略這個區塊錯誤, 並序列化它呢? 

    ps. 不能放棄其它的名稱空間.


    2012年10月1日 上午 09:48

所有回覆

  • value有固定介面規格嗎?

    有考慮覆寫序列化嗎?

    請參考

    如何覆寫編碼的 SOAP XML 序列化

    2012年10月1日 下午 04:23
  • 如果XML文件有Namespace, 則反序列化時也要加入Namespace定義, 請參考:How do I deserialize XML namespaces in C# (System.Xml.Serialization)?
    2012年10月2日 上午 08:53
  • 謝謝 Litfal, tihs 的回覆,

    我的問題是因為 xml 有namespace 的瑕玼, 所以在反序列化時出現了 System.InvalidOperationException 未定義的命名空間前置詞 'axis2ns22'

    但我必須要忽略這個區域的 namespace 的錯誤進行反序列化, 且不能放棄其他區域的namespace. 

    目前我還在試 Litfal 提供的文件, 

    其實我昨天有到一個連結 http://social.msdn.microsoft.com/Forums/en-US/xmlandnetfx/thread/97995527-7b14-48ec-9b6c-39eb11d5adcb/

    同樣是用 SoapAttributeOverrides 但他是處理serialization, 不確定在deserialization一樣可行.

    有收獲再回報大家. (update at 2012/10/02)


    2012年10月2日 上午 11:10

  • 我參考了  http://msdn.microsoft.com/zh-tw/library/athddy89(v=vs.80).aspx

    沒有解決這個問題, 我想SoapAttributeOverrides 是用來處理mapping, 對於 formatted wellness xml 是沒有效果.

    經過一輪亂測試及reflector發現, 

    1. XMLSchema的宣告 xsi:type 在反序列化時會去處理attribute內容的名稱空間 "axis2ns2:date" .

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    ...
    <ax23:value xsi:type="axis2ns2:date">

    2. 當xsi:type 裡頭有名稱空間時, 在實際XML read 前會先去LookupNamespace, 若不存在會抛出exception, 程式如下, 故還輪不到SoapAttributeOverrides出場

    internal XmlQualifiedName ToXmlQualifiedName(string value, bool decodeName)
    {
        int length = (value == null) ? -1 : value.LastIndexOf(':');
        string name = (length < 0) ? null : value.Substring(0, length);
        string str2 = value.Substring(length + 1);
        if (decodeName)
        {
            name = XmlConvert.DecodeName(name);
            str2 = XmlConvert.DecodeName(str2);
        }
        if ((name == null) || (name.Length == 0))
        {
            return new XmlQualifiedName(this.r.NameTable.Add(value), this.r.LookupNamespace(string.Empty));
        }
        string ns = this.r.LookupNamespace(name);
        if (ns == null)
        {
            throw new InvalidOperationException(Res.GetString("XmlUndefinedAlias", new object[] { name }));
        }
        return new XmlQualifiedName(this.r.NameTable.Add(str2), ns);
    }
    
     


    3. 總結, 我現在只好爛招解決了, 先用stream接起來, 然後把有問題的內容用regex修正 (幫忙加入namespace), 再交給 xmlserializer 來處理. 如下

    <ax23:value xsi:type="axis2ns2:date" xmlns:axis2ns2="http://namespace.miss">

    結果 value 已經可以序列化成 XmlNode, 然後再另行處理內容的序列化即可.

    如果描述內容有誤請指教, 謝謝 (update at 2012/10/03)


    • 已編輯 hectorlee369 2012年10月3日 上午 04:36 錯字修正
    2012年10月3日 上午 04:29