• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評論-2670  文章-0  trackbacks-0
                為了紀念自己為了明天的XML考試復習了半天,特地根據MSDN描述的標準做了一個XML的解釋器。接口類似DOM和SAX的混合體。
                目前什么都不支持,不過以后打算做完DTD和XPath。XSD和XSL就先算了。反正是寫著玩的。把代碼貼出來先。這個代碼使用了自己開發的一套C++基礎庫。

                接口:
              1 /*******************************************************************************
              2 Vczh Library++ 2.0
              3 XML
              4 開發者:陳梓瀚
              5 
              6 接口:
              7 類:
              8 函數:
              9 *******************************************************************************/
             10 
             11 #ifndef VL_XML
             12 #define VL_XML
             13 
             14 #include "..\Data\Data\VL_Data_String.h"
             15 #include "..\Data\Data\VL_Data_List.h"
             16 #include "..\Data\VL_Stream.h"
             17 #include "..\Data\VL_Uniop.h"
             18 
             19 
             20 namespace vl
             21 {
             22     namespace xml
             23     {
             24         using namespace collection;
             25         using namespace stream;
             26         using namespace uniop;
             27 
             28         enum VLE_XMLNodeType
             29         {
             30             vxntInstruction,
             31             vxntDTD,
             32             vxntElement,
             33             vxntComment,
             34             vxntText,
             35             vxntCData,
             36             vxntAttribute,
             37             vxntDocument
             38         };
             39 
             40         class VL_XMLInstruction;
             41         class VL_XMLDTD;
             42         class VL_XMLElement;
             43         class VL_XMLComment;
             44         class VL_XMLText;
             45         class VL_XMLCData;
             46         class VL_XMLAttribute;
             47         class VL_XMLDocument;
             48 
             49         class VL_XMLError : public VL_Base
             50         {
             51         public:
             52             VUnicodeString                Message;
             53             VInt                        Start;
             54             enum CodeType
             55             {
             56                 UnavailableVersion,
             57                 UnavailableIndex,
             58                 UnavailableName,
             59                 DuplicatedName,
             60                 UnavailableText,
             61                 FileDestroyed,
             62                 FileMistake
             63             }                            Code;
             64 
             65             VL_XMLError(VUnicodeString aMessage , CodeType aCode);
             66             VL_XMLError(VUnicodeString aMessage , CodeType aCode , VInt aStart);
             67         };
             68 
             69         class VL_XMLNode : public VL_Base
             70         {
             71         protected:
             72             VL_XMLNode*                    FParent;
             73             VL_XMLDocument*                FDocument;
             74 
             75             VL_XMLNode(VL_XMLNode* Parent);
             76         public:
             77             ~VL_XMLNode();
             78 
             79             virtual VLE_XMLNodeType        GetType()=0;
             80             virtual void                GetXML(VL_UniBuilder& XML)=0;
             81             VUnicodeString                GetXMLText();
             82         };
             83 
             84         class VL_XMLNodePtr : public VL_Base
             85         {
             86         public:
             87             typedef VL_List<VL_XMLNodePtr , false>        List;
             88         protected:
             89             VL_AutoPtr<VL_XMLNode>        FNode;
             90         public:
             91             VL_XMLNodePtr();
             92             VL_XMLNodePtr(VL_XMLNode* Node);
             93             VL_XMLNodePtr(const VL_XMLNodePtr& Ptr);
             94             ~VL_XMLNodePtr();
             95 
             96             VL_XMLInstruction*            GetInstruction();
             97             VL_XMLDTD*                    GetDTD();
             98             VL_XMLElement*                GetElement();
             99             VL_XMLComment*                GetComment();
            100             VL_XMLText*                    GetText();
            101             VL_XMLCData*                GetCData();
            102             VL_XMLAttribute*            GetAttribute();
            103             VL_XMLNode*                    operator->();
            104         };
            105 
            106         class VL_XMLDecoder;
            107         class VL_XMLDocument : public VL_XMLNode
            108         {
            109         protected:
            110             VUnicodeString                FVersion;
            111             VUnicodeString                FEncoding;
            112             VBool                        FStandAlone;
            113             VBool                        FUseDeclaration;
            114             VL_XMLNodePtr::List            FPrologs;
            115             VL_XMLNodePtr::List            FTails;
            116             VL_XMLNodePtr                FRootElement;
            117             VL_XMLDecoder*                FDecoder;
            118 
            119             void                        InternalLoad(VUnicodeString String);
            120         public:
            121             VL_XMLDocument();
            122             ~VL_XMLDocument();
            123 
            124             VLE_XMLNodeType                GetType();
            125             void                        GetXML(VL_UniBuilder& XML);
            126             VUnicodeString                GetHeadXMLText();
            127             VUnicodeString                GetBodyXMLText();
            128 
            129             void                        Save(IVL_OutputStream* Stream , VBool WriteBOM);
            130             void                        Save(VUnicodeString& String);
            131             void                        Load(IVL_InputStream* Stream , VLE_CharEncode Encode=vceBOM);    /*Error:FileMistake*/
            132             void                        Load(VUnicodeString String);                                    /*Error:FileMistake*/
            133             void                        Clear();
            134 
            135             VUnicodeString                GetVersion();
            136             void                        SetVersion(VUnicodeString Version);                                /*Error:UnavailableVersion*/
            137             VUnicodeString                GetEncoding();
            138             void                        SetEncoding(VUnicodeString Encoding);
            139             VBool                        GetStandAlone();
            140             void                        SetStandAlone(VBool Use);
            141             VBool                        GetUseDeclaration();
            142             void                        SetUseDeclaration(VBool Use);
            143 
            144             VInt                        GetPrologCount();
            145             VL_XMLNodePtr                GetProlog(VInt Index);                                            /*Error:UnavailableIndex*/
            146             VL_XMLNodePtr                CreatePrologInstruction(VUnicodeString Name , VInt Index=-1);    /*Error:UnavailableName,UnavailableIndex*/
            147             VL_XMLNodePtr                CreatePrologDTD(VInt Index=-1);                                    /*Error:UnavailableIndex*/
            148             VL_XMLNodePtr                CreatePrologComment(VUnicodeString Value , VInt Index=-1);        /*Error:UnavailableText,UnavailableIndex*/
            149             void                        DeleteProlog(VInt Index);                                        /*Error:UnavailableIndex*/
            150 
            151             VInt                        GetTailCount();
            152             VL_XMLNodePtr                GetTail(VInt Index);                                            /*Error:UnavailableIndex*/
            153             VL_XMLNodePtr                CreateTailComment(VUnicodeString Value , VInt Index=-1);        /*Error:UnavailableText,UnavailableIndex*/
            154             void                        DeleteTail(VInt Index);                                            /*Error:UnavailableIndex*/
            155 
            156             VL_XMLNodePtr                GetRootElement();
            157             VBool                        IsValidatedName(VUnicodeString Name);
            158         };
            159 
            160         class VL_XMLTag : public VL_XMLNode
            161         {
            162         protected:
            163             VUnicodeString                FName;
            164             VL_XMLNodePtr::List            FAttributes;
            165 
            166             VInt                        IndexOfAttribute(VUnicodeString Name);
            167             void                        GetNodeHeadXML(VL_UniBuilder& XML);
            168 
            169             VL_XMLTag(VL_XMLNode* Parent);
            170         public:
            171             ~VL_XMLTag();
            172 
            173             VUnicodeString                GetName();
            174             void                        SetName(VUnicodeString Name);                                    /*Error:UnavailableName*/
            175             VUnicodeString                GetNamespace();
            176             VUnicodeString                GetLocal();
            177 
            178             VL_XMLNodePtr                CreateAttribute(VUnicodeString Name , VUnicodeString Value);    /*Error:UnavailableName,DuplicatedName,UnavailableText*/
            179             VBool                        ContainsAttribute(VUnicodeString Name);
            180             void                        DeleteAttribute(VUnicodeString Name);                            /*Error:UnavailableName*/
            181             VInt                        GetAttributeCount();
            182             VL_XMLNodePtr                GetAttribute(VUnicodeString Name);                                /*Error:UnavailableName*/
            183             VL_XMLNodePtr                GetAttribute(VInt Index);                                        /*Error:UnavailableIndex*/
            184         };
            185 
            186         class VL_XMLInstruction : public VL_XMLTag
            187         {
            188             friend class VL_XMLDocument;
            189             friend class VL_XMLElement;
            190         protected:
            191             VL_XMLInstruction(VL_XMLNode* Parent);
            192         public:
            193             ~VL_XMLInstruction();
            194 
            195             VLE_XMLNodeType                GetType();
            196             void                        GetXML(VL_UniBuilder& XML);
            197         };
            198 
            199         class VL_XMLElement : public VL_XMLTag
            200         {
            201             friend class VL_XMLDocument;
            202         protected:
            203             VL_XMLNodePtr::List            FChildren;
            204 
            205             VL_XMLElement(VL_XMLNode* Parent);
            206         public:
            207             ~VL_XMLElement();
            208 
            209             VLE_XMLNodeType                GetType();
            210             void                        GetXML(VL_UniBuilder& XML);
            211 
            212             VL_XMLNodePtr                CreateInstruction(VUnicodeString Name , VInt Index=-1);            /*Error:UnavailableName,UnavailableIndex*/
            213             VL_XMLNodePtr                CreateElement(VUnicodeString Name , VInt Index=-1);                /*Error:UnavailableName,UnavailableIndex*/
            214             VL_XMLNodePtr                CreateComment(VUnicodeString Text , VInt Index=-1);                /*Error:UnavailableText,UnavailableIndex*/
            215             VL_XMLNodePtr                CreateText(VUnicodeString Text , VInt Index=-1);                /*Error:UnavailableText,UnavailableIndex*/
            216             VL_XMLNodePtr                CreateCData(VUnicodeString Text , VInt Index=-1);                /*Error:UnavailableText,UnavailableIndex*/
            217             VL_XMLNodePtr::List&        GetChildren();
            218         };
            219 
            220         class VL_XMLComment : public VL_XMLNode
            221         {
            222             friend class VL_XMLDocument;
            223             friend class VL_XMLElement;
            224         protected:
            225             VUnicodeString                FText;
            226 
            227             VL_XMLComment(VL_XMLNode* Parent);
            228         public:
            229             ~VL_XMLComment();
            230 
            231             VLE_XMLNodeType                GetType();
            232             void                        GetXML(VL_UniBuilder& XML);
            233 
            234             VUnicodeString                GetText();
            235             void                        SetText(VUnicodeString Text);                                    /*Error:UnavailableText*/
            236         };
            237 
            238         class VL_XMLText : public VL_XMLNode
            239         {
            240             friend class VL_XMLElement;
            241         protected:
            242             VUnicodeString                FText;
            243 
            244             VL_XMLText(VL_XMLNode* Parent);
            245         public:
            246             ~VL_XMLText();
            247 
            248             VLE_XMLNodeType                GetType();
            249             void                        GetXML(VL_UniBuilder& XML);
            250 
            251             VUnicodeString                GetText();
            252             void                        SetText(VUnicodeString Text);                                    /*Error:UnavailableText*/
            253         };
            254 
            255         class VL_XMLCData : public VL_XMLNode
            256         {
            257             friend class VL_XMLElement;
            258         protected:
            259             VUnicodeString                FText;
            260 
            261             VL_XMLCData(VL_XMLNode* Parent);
            262         public:
            263             ~VL_XMLCData();
            264 
            265             VLE_XMLNodeType                GetType();
            266             void                        GetXML(VL_UniBuilder& XML);
            267 
            268             VUnicodeString                GetText();
            269             void                        SetText(VUnicodeString Text);                                    /*Error:UnavailableText*/
            270         };
            271 
            272         class VL_XMLAttribute : public VL_XMLNode
            273         {
            274             friend class VL_XMLTag;
            275         protected:
            276             VUnicodeString                FName;
            277             VUnicodeString                FText;
            278             VBool                        FQuot;
            279 
            280             VL_XMLAttribute(VL_XMLNode* Parent);
            281         public:
            282             ~VL_XMLAttribute();
            283 
            284             VLE_XMLNodeType                GetType();
            285             void                        GetXML(VL_UniBuilder& XML);
            286 
            287             VUnicodeString                GetName();
            288             VUnicodeString                GetNamespace();
            289             VUnicodeString                GetLocal();
            290             VUnicodeString                GetText();
            291             void                        SetText(VUnicodeString Text);                                    /*Error:UnavailableText*/
            292         };
            293     }
            294 }
            295 
            296 #endif

                使用自己做的正則表達式構造的一系列XML分析工具:
              1 /*********************************************************************************************************
              2 VL_XMLDecoder
              3 *********************************************************************************************************/
              4 
              5     struct VLS_XMLString
              6     {
              7         PWChar                    Start;
              8         VInt                    Length;
              9 
             10         VLS_XMLString()
             11         {
             12             Start=0;
             13             Length=0;
             14         }
             15 
             16         VLS_XMLString(PWChar aStart , VInt aLength)
             17         {
             18             Start=aStart;
             19             Length=aLength;
             20         }
             21 
             22         VBool Is(PCWChar String)
             23         {
             24             PCWChar Buffer=Start;
             25             while(*String)
             26             {
             27                 if(*Buffer++!=*String++)
             28                 {
             29                     return false;
             30                 }
             31             }
             32             return true;
             33         }
             34 
             35         VUnicodeString ToString()
             36         {
             37             return VUnicodeString(Start,Length);
             38         }
             39     };
             40 
             41     struct VLS_XMLAttribute
             42     {
             43         typedef VL_List<VLS_XMLAttribute , true>    List;
             44 
             45         VLS_XMLString            Name;
             46         VLS_XMLString            Value;
             47     };
             48 
             49     struct VLS_XMLElement
             50     {
             51         VLS_XMLAttribute::List    Attributes;
             52         VLS_XMLString            Name;
             53         VWChar                    StartChar;
             54         VWChar                    EndChar;
             55     };
             56 
             57     class VL_XMLDecoder : public VL_Base
             58     {
             59     public:
             60         VL_RegMatch Reg_CData;
             61         VL_RegMatch Reg_Text;
             62         VL_RegMatch Reg_Comment;
             63         VL_RegMatch Reg_Name;
             64         VL_RegMatch Reg_Value;
             65 
             66         VL_XMLDecoder():
             67             Reg_CData(L"\\<!\\[CDATA\\[([^\\]]|\\][^\\]]|\\]\\][^\\>])*\\]\\]\\>"),
             68             Reg_Text(L"[^\\<\\>]+"),
             69             Reg_Comment(L"\\<!\\-\\-([^\\-]|\\-[^\\-]|\\-\\-[^\\>])*\\-\\-\\>"),
             70             Reg_Name(L"[a-zA-Z_][a-zA-Z0-9\\-_.:]*"),
             71             Reg_Value(L"\"[^\"]*\"")
             72         {
             73         }
             74 
             75         void PassWhite(VLS_XMLString& String)
             76         {
             77             while(String.Length)
             78             {
             79                 switch(*String.Start)
             80                 {
             81                 case L' ':case L'\t':case L'\r':case L'\n':
             82                     String.Start++;
             83                     String.Length--;
             84                     break;
             85                 default:
             86                     return;
             87                 }
             88             }
             89         }
             90 
             91         VLS_XMLString GetCData(VLS_XMLString& Input)
             92         {
             93             VInt Length=Reg_CData.MatchBuffer(Input.Start);
             94             if(Length==-1)
             95             {
             96                 return VLS_XMLString();
             97             }
             98             else
             99             {
            100                 VLS_XMLString Result(Input.Start+9,Length-12);
            101                 Input.Start+=Length;
            102                 Input.Length-=Length;
            103                 return Result;
            104             }
            105         }
            106 
            107         VLS_XMLString GetText(VLS_XMLString& Input)
            108         {
            109             VInt Length=Reg_Text.MatchBuffer(Input.Start);
            110             if(Length==-1)
            111             {
            112                 return VLS_XMLString();
            113             }
            114             else
            115             {
            116                 VLS_XMLString Result(Input.Start,Length);
            117                 Input.Start+=Length;
            118                 Input.Length-=Length;
            119                 return Result;
            120             }
            121         }
            122 
            123         VLS_XMLString GetComment(VLS_XMLString& Input , VBool PassWhiteCharacters=false)
            124         {
            125             if(PassWhiteCharacters)PassWhite(Input);
            126             VInt Length=Reg_Comment.MatchBuffer(Input.Start);
            127             if(Length==-1)
            128             {
            129                 return VLS_XMLString();
            130             }
            131             else
            132             {
            133                 VLS_XMLString Result(Input.Start+4,Length-7);
            134                 Input.Start+=Length;
            135                 Input.Length-=Length;
            136                 return Result;
            137             }
            138         }
            139 
            140         VLS_XMLString GetName(VLS_XMLString& Input , VBool PassWhiteCharacters)
            141         {
            142             if(PassWhiteCharacters)PassWhite(Input);
            143             VInt Length=Reg_Name.MatchBuffer(Input.Start);
            144             if(Length==-1)
            145             {
            146                 return VLS_XMLString();
            147             }
            148             else
            149             {
            150                 VLS_XMLString Result(Input.Start,Length);
            151                 Input.Start+=Length;
            152                 Input.Length-=Length;
            153                 return Result;
            154             }
            155         }
            156 
            157         VLS_XMLString GetValue(VLS_XMLString& Input , VBool PassWhiteCharacters)
            158         {
            159             if(PassWhiteCharacters)PassWhite(Input);
            160             VInt Length=Reg_Value.MatchBuffer(Input.Start);
            161             if(Length==-1)
            162             {
            163                 return VLS_XMLString();
            164             }
            165             else
            166             {
            167                 VLS_XMLString Result(Input.Start+1,Length-2);
            168                 Input.Start+=Length;
            169                 Input.Length-=Length;
            170                 return Result;
            171             }
            172         }
            173 
            174         VBool Test(VLS_XMLString& Input , PCWChar String , VBool PassWhiteCharacters)
            175         {
            176             if(PassWhiteCharacters)PassWhite(Input);
            177             PWChar Buffer=Input.Start;
            178             while(*String)
            179             {
            180                 if(*Buffer++!=*String++)
            181                 {
            182                     return false;
            183                 }
            184             }
            185             Input.Length-=Buffer-Input.Start;
            186             Input.Start=Buffer;
            187             return true;
            188         }
            189 
            190         PCWChar GetElement(VLS_XMLString& Input , VLS_XMLElement& Element , VBool CompleteAttribute , VBool PassWhiteCharacters)
            191         {
            192             if(PassWhiteCharacters)PassWhite(Input);
            193             if(Test(Input,L"<?",false))
            194             {
            195                 Element.StartChar=L'?';
            196             }
            197             else if(Test(Input,L"<!",false))
            198             {
            199                 Element.StartChar=L'!';
            200             }
            201             else if(Test(Input,L"</",false))
            202             {
            203                 Element.StartChar=L'/';
            204             }
            205             else if(Test(Input,L"<",false))
            206             {
            207                 Element.StartChar=0;
            208             }
            209             else
            210             {
            211                 return L"錯誤的Element開始字符。";
            212             }
            213             Element.Name=GetName(Input,true);
            214             if(!Element.Name.Start)
            215             {
            216                 return L"錯誤的Element名稱。";
            217             }
            218             Element.Attributes.Clear();
            219             while(true)
            220             {
            221                 PassWhite(Input);
            222                 if(Test(Input,L"?>",false))
            223                 {
            224                     Element.EndChar=L'?';
            225                     break;
            226                 }
            227                 else if(Test(Input,L"/>",false))
            228                 {
            229                     Element.EndChar=L'/';
            230                     break;
            231                 }
            232                 else if(Test(Input,L">",false))
            233                 {
            234                     Element.EndChar=0;
            235                     break;
            236                 }
            237                 else
            238                 {
            239                     VLS_XMLAttribute Attribute;
            240                     Attribute.Name=GetName(Input,false);
            241                     if(Attribute.Name.Start)
            242                     {
            243                         if(Test(Input,L"=",true))
            244                         {
            245                             Attribute.Value=GetValue(Input,true);
            246                             if(!Attribute.Value.Start)
            247                             {
            248                                 return L"錯誤的Attribute值。";
            249                             }
            250                         }
            251                     }
            252                     else
            253                     {
            254                         Attribute.Value=GetValue(Input,true);
            255                     }
            256                     if(CompleteAttribute)
            257                     {
            258                         if(!Attribute.Name.Start)
            259                         {
            260                             return L"缺少Attribute名稱。";
            261                         }
            262                         else if(!Attribute.Value.Start)
            263                         {
            264                             return L"缺少Attribute值。";
            265                         }
            266                     }
            267                     Element.Attributes.Add(Attribute);
            268                 }
            269             }
            270             return 0;
            271         }
            272     };

                分析部分,其中使用了一個自己做的貪婪正則表達式分析器分析XML的編碼部分:
              1 /*********************************************************************************************************
              2 VL_XMLDocument
              3 *********************************************************************************************************/
              4 
              5     void VL_XMLDocument::InternalLoad(VUnicodeString String)
              6     {
              7         if(!FDecoder)
              8         {
              9             FDecoder=new VL_XMLDecoder;
             10         }
             11         VLS_XMLString Input(String.Buffer(),String.Length());
             12         {
             13             /*檢查第一個標記是否<?xml?>*/
             14             FUseDeclaration=false;
             15             VLS_XMLString Head=Input;
             16             VLS_XMLElement Element;
             17             PCWChar ErrorMessage=FDecoder->GetElement(Head,Element,true,false);
             18             if(!ErrorMessage)
             19             {
             20                 if(Element.Name.Is(L"xml"))
             21                 {
             22                     /*獲取<?xml?>標記的三個屬性*/
             23                     FUseDeclaration=true;
             24                     if(Element.Attributes.GetCount()>=1)
             25                     {
             26                         if(Element.Attributes[0].Name.Is(L"version"))
             27                         {
             28                             if(Element.Attributes[0].Value.Is(L"1.0"))
             29                             {
             30                                 FVersion=L"1.0";
             31                             }
             32                             else
             33                             {
             34                                 throw VL_XMLError(L"錯誤的版本號,分析器只支持1.0版本的XML文件。",VL_XMLError::FileMistake,Head.Start-String.Buffer());
             35                             }
             36                         }
             37                         else
             38                         {
             39                             throw VL_XMLError(L"?xml標記的第一個屬性必須是version。",VL_XMLError::FileMistake,Head.Start-String.Buffer());
             40                         }
             41                     }
             42                     if(Element.Attributes.GetCount()>=2)
             43                     {
             44                         if(Element.Attributes[1].Name.Is(L"encoding"))
             45                         {
             46                             FEncoding=Element.Attributes[1].Value.ToString();
             47                         }
             48                         else
             49                         {
             50                             throw VL_XMLError(L"?xml標記的第二個屬性必須是encoding。",VL_XMLError::FileMistake,Head.Start-String.Buffer());
             51                         }
             52                     }
             53                     if(Element.Attributes.GetCount()>=3)
             54                     {
             55                         if(Element.Attributes[2].Name.Is(L"standalone"))
             56                         {
             57                             if(Element.Attributes[2].Value.Is(L"yes"))
             58                             {
             59                                 FStandAlone=true;
             60                             }
             61                             else if(Element.Attributes[2].Value.Is(L"no"))
             62                             {
             63                                 FStandAlone=false;
             64                             }
             65                             else
             66                             {
             67                                 throw VL_XMLError(L"?xml的standalone的屬性只能取\"yes\"或\"no\"",VL_XMLError::FileMistake,Head.Start-String.Buffer());
             68                             }
             69                         }
             70                         else
             71                         {
             72                             throw VL_XMLError(L"?xml標記的第三個屬性必須是encoding。",VL_XMLError::FileMistake,Head.Start-String.Buffer());
             73                         }
             74                     }
             75                     if(Element.Attributes.GetCount()>=4)
             76                     {
             77                         throw VL_XMLError(L"?xml標記只能有version、encoding和standalone屬性。",VL_XMLError::FileMistake,Head.Start-String.Buffer());
             78                     }
             79                     Input=Head;
             80                 }
             81             }
             82             else
             83             {
             84                 throw VL_XMLError(ErrorMessage,VL_XMLError::FileMistake,Input.Start-String.Buffer());
             85             }
             86         }
             87         /*獲取Prolog*/
             88         VLS_XMLElement Element;
             89         while(true)
             90         {
             91             /*嘗試分析Comment*/
             92             VLS_XMLString Comment=FDecoder->GetComment(Input,true);
             93             if(Comment.Start)
             94             {
             95                 CreatePrologComment(Comment.ToString());
             96             }
             97             else
             98             {
             99                 /*分析Processing Instruction*/
            100                 PCWChar ErrorMessage=FDecoder->GetElement(Input,Element,true,true);
            101                 if(ErrorMessage)
            102                 {
            103                     throw VL_XMLError(ErrorMessage,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            104                 }
            105                 else if(Element.StartChar==L'?')
            106                 {
            107                     if(Element.EndChar!=L'?')
            108                     {
            109                         throw VL_XMLError(VUnicodeString(L"Processing Instruction標記必須使用?>結束。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            110                     }
            111                     try
            112                     {
            113                         VL_XMLInstruction* Instruction=CreatePrologInstruction(Element.Name.ToString()).GetInstruction();
            114                         for(VInt i=0;i<Element.Attributes.GetCount();i++)
            115                         {
            116                             Instruction->CreateAttribute(Element.Attributes[i].Name.ToString(),Element.Attributes[i].Value.ToString());
            117                         }
            118                     }
            119                     catch(VL_XMLError& e)
            120                     {
            121                         e.Start=Input.Start-String.Buffer();
            122                         throw e;
            123                     }
            124                 }
            125                 else if(Element.StartChar==0)
            126                 {
            127                     break;
            128                 }
            129                 else
            130                 {
            131                     throw VL_XMLError(VUnicodeString(L"遇到不明標記類型:<。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            132                 }
            133             }
            134         }
            135         /*填充RootElement信息*/
            136         VL_List<VL_XMLElement* , true> ElementStack;
            137         VL_XMLElement* Last=FRootElement.GetElement();
            138         ElementStack.Add(Last);
            139         try
            140         {
            141             FRootElement.GetElement()->SetName(Element.Name.ToString());
            142             for(VInt i=0;i<Element.Attributes.GetCount();i++)
            143             {
            144                 Last->CreateAttribute(Element.Attributes[i].Name.ToString(),Element.Attributes[i].Value.ToString());
            145             }
            146             switch(Element.EndChar)
            147             {
            148             case L'/':
            149                 ElementStack.Fetch();
            150                 Last=0;
            151                 break;
            152             case 0:
            153                 break;
            154             default:
            155                 throw VL_XMLError(VUnicodeString(L"Element標記必須使用/>或>結束。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            156             }
            157         }
            158         catch(VL_XMLError& e)
            159         {
            160             e.Start=Input.Start-String.Buffer();
            161             throw e;
            162         }
            163         /*填充RootElement內容*/
            164         while(Last)
            165         {
            166             VLS_XMLString XMLString=FDecoder->GetComment(Input);
            167             if(XMLString.Start)
            168             {
            169                 Last->CreateComment(XMLString.ToString());
            170             }
            171             else if((XMLString=FDecoder->GetCData(Input)).Start)
            172             {
            173                 Last->CreateCData(XMLString.ToString());
            174             }
            175             else if((XMLString=FDecoder->GetText(Input)).Start)
            176             {
            177                 Last->CreateText(XMLString.ToString());
            178             }
            179             else
            180             {
            181                 PCWChar ErrorMessage=FDecoder->GetElement(Input,Element,true,false);
            182                 if(ErrorMessage)
            183                 {
            184                     throw VL_XMLError(ErrorMessage,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            185                 }
            186                 else if(Element.StartChar==L'?')
            187                 {
            188                     if(Element.EndChar!=L'?')
            189                     {
            190                         throw VL_XMLError(VUnicodeString(L"Processing Instruction標記必須使用?>結束。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            191                     }
            192                     try
            193                     {
            194                         VL_XMLInstruction* Instruction=Last->CreateInstruction(Element.Name.ToString()).GetInstruction();
            195                         for(VInt i=0;i<Element.Attributes.GetCount();i++)
            196                         {
            197                             Instruction->CreateAttribute(Element.Attributes[i].Name.ToString(),Element.Attributes[i].Value.ToString());
            198                         }
            199                     }
            200                     catch(VL_XMLError& e)
            201                     {
            202                         e.Start=Input.Start-String.Buffer();
            203                         throw e;
            204                     }
            205                 }
            206                 else if(Element.StartChar==0)
            207                 {
            208                     try
            209                     {
            210                         VL_XMLElement* Current=Last->CreateElement(Element.Name.ToString()).GetElement();
            211                         if(Element.EndChar==L'/')
            212                         {
            213                         }
            214                         else if(Element.EndChar==0)
            215                         {
            216                             ElementStack.Add(Last=Current);
            217                         }
            218                         else
            219                         {
            220                             throw VL_XMLError(VUnicodeString(L"Element標記必須使用/>或>結束。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            221                         }
            222                         for(VInt i=0;i<Element.Attributes.GetCount();i++)
            223                         {
            224                             Current->CreateAttribute(Element.Attributes[i].Name.ToString(),Element.Attributes[i].Value.ToString());
            225                         }
            226                     }
            227                     catch(VL_XMLError& e)
            228                     {
            229                         e.Start=Input.Start-String.Buffer();
            230                         throw e;
            231                     }
            232                 }
            233                 else if(Element.StartChar==L'/')
            234                 {
            235                     if(Element.Name.ToString()!=Last->GetName())
            236                     {
            237                         throw VL_XMLError(VUnicodeString(L"不匹配的Element結束。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            238                     }
            239                     else if(Element.EndChar!=0)
            240                     {
            241                         throw VL_XMLError(VUnicodeString(L"Element結束標記必須使用>結束。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            242                     }
            243                     else if(Element.Attributes.GetCount()>0)
            244                     {
            245                         throw VL_XMLError(VUnicodeString(L"Element結束標記不能有Attribute。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            246                     }
            247                     else
            248                     {
            249                         ElementStack.Fetch();
            250                         if(ElementStack.GetCount())
            251                         {
            252                             Last=ElementStack[ElementStack.GetCount()-1];
            253                         }
            254                         else
            255                         {
            256                             Last=0;
            257                         }
            258                     }
            259                 }
            260                 else
            261                 {
            262                     throw VL_XMLError(VUnicodeString(L"遇到不明標記類型:<。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            263                 }
            264             }
            265         }
            266         /*獲取Tail*/
            267         while(true)
            268         {
            269             VLS_XMLString XMLString=FDecoder->GetComment(Input,true);
            270             if(XMLString.Start)
            271             {
            272                 CreateTailComment(XMLString.ToString());
            273             }
            274             else
            275             {
            276                 break;
            277             }
            278         }
            279         if(Input.Length)
            280         {
            281             throw VL_XMLError(VUnicodeString(L"XML文件末尾出現多余字符。")+Element.StartChar,VL_XMLError::FileMistake,Input.Start-String.Buffer());
            282         }
            283     }
            284 
            285     void VL_XMLDocument::Load(IVL_InputStream* Stream , VLE_CharEncode Encode)
            286     {
            287         VUnicodeString String;
            288         VL_TextInput Input(Stream,false,Encode);
            289         if(Input.GetEncode()==vceMbcs)
            290         {
            291             VUnicodeString Head;
            292             VLE_CharEncode NewEncode=vceMbcs;
            293             VInt Position=Stream->Position();
            294             VChar Current=0;
            295             VBool NoEncoding=true;
            296             /*讀取到">"結束的字符串*/
            297             while(Stream->Read(&Current,sizeof(Current)))
            298             {
            299                 if(Current=='>')
            300                 {
            301                     break;
            302                 }
            303             }
            304             /*如果讀取成功則進行encoding判斷*/
            305             if(Current=='>')
            306             {
            307                 /*獲取<?xml?>標記*/
            308                 VInt Count=Stream->Position()-Position;
            309                 Stream->MoveTo(Position);
            310                 Input.Read(Head,Count);
            311                 VL_RegExp Declaration(L"\\s*\\<\\?\\s*xml(\\s+(?:<#attribute>[a-zA-Z_][a-zA-Z0-9\\-_.]*)\\s*=\\s*\"(?:<#value>[^\"]*)\")*\\s*\\?\\>",true);
            312                 VL_RegExp::ResultPtr Result=Declaration.MatchWhole(Head);
            313                 /*如果獲取成功則獲取encoding屬性*/
            314                 if(Result->IsMatched())
            315                 {
            316                     if(Result->HasStorage(L"attribute"))
            317                     {
            318                         Count=Result->GetStorageCount(L"attribute");
            319                         for(VInt i=0;i<Count;i++)
            320                         {
            321                             if(Result->GetStorage(L"attribute",i)==L"encoding")
            322                             {
            323                                 /*encoding存在,獲取編碼*/
            324                                 VUnicodeString Encoding=Result->GetStorage(L"value",i).LowerCase();
            325                                 if(Encoding==L"utf-8")
            326                                 {
            327                                     NewEncode=vceUtf8;
            328                                     NoEncoding=false;
            329                                 }
            330                                 else if(Encoding==L"utf-16")
            331                                 {
            332                                     NewEncode=vceUtf16;
            333                                     NoEncoding=false;
            334                                 }
            335                                 break;
            336                             }
            337                         }
            338                     }
            339                 }
            340             }
            341             /*根據不同的Encoding狀況組裝完整的XML字符串*/
            342             if(NoEncoding)
            343             {
            344                 Stream->MoveTo(Position);
            345                 Input.Read(String);
            346             }
            347             else
            348             {
            349                 VL_TextInput Input2(Stream,false,NewEncode);
            350                 Input2.Read(String);
            351                 String.Insert(0,Head);
            352             }
            353         }
            354         else
            355         {
            356             Input.Read(String);
            357         }
            358         Load(String);
            359     }
            360 
            361     void VL_XMLDocument::Load(VUnicodeString String)
            362     {
            363         VUnicodeString aVersion=FVersion;
            364         VUnicodeString aEncoding=FEncoding;
            365         VBool aStandAlone=FStandAlone;
            366         VBool aUseDeclaration=FUseDeclaration;
            367         VL_XMLNodePtr aRootElement=FRootElement;
            368         VL_XMLNodePtr::List aPrologs=FPrologs;
            369         VL_XMLNodePtr::List aTails=FTails;
            370         try
            371         {
            372             Clear();
            373             InternalLoad(String);
            374         }
            375         catch(VL_XMLError& e)
            376         {
            377             FVersion=aVersion;
            378             FEncoding=aEncoding;
            379             FStandAlone=aStandAlone;
            380             FUseDeclaration=aUseDeclaration;
            381             FRootElement=aRootElement;
            382             FPrologs=aPrologs;
            383             FTails=aTails;
            384             throw e;
            385         }
            386     }
            posted on 2008-06-19 05:28 陳梓瀚(vczh) 閱讀(3155) 評論(8)  編輯 收藏 引用 所屬分類: C++

            評論:
            # re: 做了一個XML解釋器 2008-06-19 07:45 | soulfvi
            .................................
            說什么好呢  回復  更多評論
              
            # re: 做了一個XML解釋器 2008-06-19 16:22 | toperray
            很好,小伙子,堅持下去,呵呵。  回復  更多評論
              
            # re: 做了一個XML解釋器 2008-06-19 17:12 | 浪跡天涯
            mark 學習學習  回復  更多評論
              
            # re: 做了一個XML解釋器 2008-06-19 18:03 | werw
            強悍啊~~~~~~~~~  回復  更多評論
              
            # re: 做了一個XML解釋器 2008-06-19 21:25 | 空明流轉
            日,你真他媽的有閑工夫。  回復  更多評論
              
            # re: 做了一個XML解釋器 2008-06-19 21:58 | 陳梓瀚(vczh)
            事實證明,復習到囧囧有神的時候最好的緩解辦法就是信手拈一個程序了……  回復  更多評論
              
            # re: 做了一個XML解釋器 2008-06-20 01:23 | rwei
            太有才了  回復  更多評論
              
            # re: 做了一個XML解釋器 2008-06-26 05:46 | Vampire.Kiss
            其實仔細看MSDN的話。
            你會發現有H內容  回復  更多評論
              
            久久久久人妻一区二区三区 | 久久久久久久久久久| 精品久久777| 久久99精品久久久久久久久久| 久久婷婷五月综合色99啪ak| 久久久久久A亚洲欧洲AV冫| 国产免费久久久久久无码| 久久久精品午夜免费不卡| 国内精品久久久久影院一蜜桃| 久久这里只有精品首页| 久久婷婷色综合一区二区| 狠狠色丁香婷婷久久综合| 伊人色综合久久天天人守人婷| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 亚洲精品国产综合久久一线| 久久国产香蕉一区精品| 国产精品免费久久| 久久亚洲欧洲国产综合| 久久亚洲精品国产亚洲老地址| 久久福利资源国产精品999| 精品人妻伦九区久久AAA片69| 久久精品国产乱子伦| 久久人人妻人人爽人人爽| 久久精品国产亚洲AV高清热| 久久夜色tv网站| 久久中文精品无码中文字幕| 国产69精品久久久久观看软件| 7777精品久久久大香线蕉| 99久久精品午夜一区二区 | 久久久噜噜噜久久| 久久久久国产精品人妻| 成人综合伊人五月婷久久| 国产精品午夜久久| 久久久亚洲AV波多野结衣| 国产精品美女久久久| 欧美伊人久久大香线蕉综合69| 国产成人久久精品一区二区三区| 丁香五月网久久综合| 日日狠狠久久偷偷色综合免费| 精品久久久久久国产| 免费观看成人久久网免费观看|