Ϫf dZddlmZddlZddlZddlmZmZddlm Z m Z ddl m Z ddl mZddlmZmZd j%e e d d d dZej(eed dZdZdZdZeeZej9edzZeeZej9efdZefdZ Gdde!Z"GddZ#Gdde#Z$Gdde#Z%Gdde#Z&Gd d!e&Z'Gd"d#e&Z(Gd$d%e&Z)d&Z*e*Z+Gd'd(e&Z,Gd)d*e#Z-d+Z.d,Z/Gd-d.eZ0d/Z1d0Z2d1Z3d2Z4Gd3d4Z5y)5a Micro Document Object Model: a partial DOM implementation with SUX. This is an implementation of what we consider to be the useful subset of the DOM. The chief advantage of this library is that, not being burdened with standards compliance, it can remain very stable between versions. We can also implement utility 'pythonic' ways to access and mutate the XML tree. Since this has not subjected to a serious trial by fire, it is not recommended to use this outside of Twisted applications. However, it seems to work just fine for the documentation generator, which parses a fairly representative sample of XML. Microdom mainly focuses on working with HTML and XHTML. This module is now deprecated. ) annotationsN)BytesIOStringIO)VersiongetVersionString)ioType)InsensitiveDict) ParseError XMLParserz)twisted.web.microdom was deprecated at {}Twisted ) stacklevelcg}|j}|g}t|dkDrF|jd}|j|k(r|||j|ddt|dkDrF|S)a3 Return a list of all child elements of C{iNode} with a name matching C{name}. Note that this implementation does not conform to the DOM Level 1 Core specification because it may return C{iNode}. @param iNode: An element at which to begin searching. If C{iNode} has a name matching C{name}, it will be included in the result. @param name: A C{str} giving the name of the elements to return. @return: A C{list} of direct or indirect child elements of C{iNode} with the name C{name}. This may include C{iNode}. rN)appendlenpopnodeName childNodesiNodenamematchesmatches_appendslicecs 6/usr/lib/python3/dist-packages/twisted/web/microdom.pygetElementsByTagNamer)sh G^^N GE e*q. IIaL ::  1 LLbq e*q. Nc |j}g}|j}|g}t|dkDrT|jd}|jj|k(r|||j |ddt|dkDrT|SNr)lowerrrrrrrs rgetElementsByTagNameNoCaser$Dsz ::.wTs&!S!HHW% LLOr cjt|tr|jd}j|yr')r(bytesdecoder+r,s rr/z_streamWriteWrapper..w[s&!U#HHW% LLOr )rr1)r.r/s` r_streamWriteWrapperr3Qs' f~  H   Hr ))&z&)z>)"z"))'z'c>|D]\}}|j||}|S)z1 Perform the exact opposite of 'escape'. replacetextcharsr-hs runescaper@r,"1||Aq!" Kr c>|D]\}}|j||}|S)z; Escape a few XML special chars with XML entities. r:r<s rescaperC{rAr ceZdZdZddZy)MismatchedTagscl|||||||f\|_|_|_|_|_|_|_yN)filenameexpectgotbegLinebegColendLineendCol)selfrHrIrJrMrNrKrLs r__init__zMismatchedTags.__init__s>vsGVWf E M K H L K L Kr c d|jd|jd|jd|jd|jd|j  S)Nz expected , got line: z col: z, began line: )rIrJrMrNrKrLrOs r__str__zMismatchedTags.__str__s8        r Nreturnr))__name__ __module__ __qualname__rPrSr rrErEs  F  r rEceZdZdZddZdZddddidfdZddddidfdZddZdd Z dd Z d Z d Z d Z dZdZdZdZy)NodeNc ||_g|_yrG) parentNoder)rOr]s rrPz Node.__init__s$r ct|jt|jk7ryt|j|jD]\}}|j|ryy)a Compare this node to C{other}. If the nodes have the same number of children and corresponding children are equal to each other, return C{True}, otherwise return C{False}. @type other: L{Node} @rtype: C{bool} FT)rrzip isEqualToNode)rOotherabs rr`zNode.isEqualToNodes[ t 3u'7'7#8 8)9)9: DAq??1% r rctrGNotImplementedError)rOr.indent addindentnewlstrip nsprefixes namespaces rwritexmlz Node.writexmls "##r c ht}|j||||||||j}|SrG)rrngetvalue) rOrhrirjrkrlrmr-rvs rtoxmlz Node.toxmls3 J aD%YO ZZ\ r c,|j|||||SrG)rn)rOr.rhrirjrks rwriteprettyxmlzNode.writeprettyxmls}}VVYeDDr c*|j||||SrG)rr)rOrhrirjrks r toprettyxmlzNode.toprettyxmlszz&)T599r ctrGrfrOdeepparents r cloneNodezNode.cloneNodes !##r c|jryy)NrrrRs r hasChildNodeszNode.hasChildNodess ??r c~t|ts td|jj |||_y)z Make the given L{Node} the last child of this node. @param child: The L{Node} which will become a child of this node. @raise TypeError: If C{child} is not a C{Node} instance. expected Node instanceN)r(r[ TypeErrorrrr]rOchilds r appendChildzNode.appendChilds4%&45 5 u%r ct|trt|ts td|jj |}||_|jj |||S)a Make the given L{Node} C{new} a child of this node which comes before the L{Node} C{ref}. @param new: A L{Node} which will become a child of this node. @param ref: A L{Node} which is already a child of this node which C{new} will be inserted before. @raise TypeError: If C{new} or C{ref} is not a C{Node} instance. @return: C{new} r)r(r[rrindexr]insert)rOnewrefis r insertBeforezNode.insertBeforesW#t$JsD,A45 5 OO ! !# & q#& r ct|ts td||jvr"|jj |d|_|S)a7 Remove the given L{Node} from this node's children. @param child: A L{Node} which is a child of this node which will no longer be a child of this node after this method is called. @raise TypeError: If C{child} is not a C{Node} instance. @return: C{child} rN)r(r[rrremover]rs r removeChildzNode.removeChildsE%&45 5 DOO # OO " "5 )#E  r ct|trt|ts td|j|ur t d||j |j j |<d|_||_y)a Replace a L{Node} which is already a child of this node with a different node. @param newChild: A L{Node} which will be made a child of this node. @param oldChild: A L{Node} which is a child of this node which will give up its position to C{newChild}. @raise TypeError: If C{newChild} or C{oldChild} is not a C{Node} instance. @raise ValueError: If C{oldChild} is not a child of this C{Node}. rz$oldChild is not a child of this nodeN)r(r[rr] ValueErrorrr)rOnewChildoldChilds r replaceChildzNode.replaceChild sj(D)Hd1K45 5   d *CD D;C--h78""r c |jdSNr~rRs r lastChildzNode.lastChild$sr""r cLt|jr|jdSyr")rrrRs r firstChildzNode.firstChild's t ??1% %r rG)rd  rrN)rVrWrXrrPr`rnrrrtrvr{rrrrrrrrYr rr[r[srH&  $2BaBRTE:$  *$#.#r r[c~eZdZUddZddZdZded<dZeZe dZ d Z d d d did fd Z d Z d ZdZdZdZy)DocumentNcVtj||r|j|yyrG)r[rPr)rOdocumentElements rrPzDocument.__init__:s$ d    _ - r rct}|j|_|r|jjd|}n |j}|j ||SNr})rdoctyperr{r)rOryrzdnewEls rr{zDocument.cloneNode?sK JLL ((221d;E((E er z None | strrcd|j|jk(xrtj||SrG)rr[r`rOns risEqualToDocumentzDocument.isEqualToDocumentKs'  )Jt/A/A$/JJr c |jdSr"r~rRs rrzDocument.documentElementPsq!!r c^|jr tdtj||y)a Make the given L{Node} the I{document element} of this L{Document}. @param child: The L{Node} to make into this L{Document}'s document element. @raise ValueError: If this document already has a document element. zOnly one element per document.N)rrr[rrs rrzDocument.appendChildTs' ??=> > u%r rdc t|}|d|z|jr|d|jd||jj|||||||y)Nzz >!$D!!$//2t^,1B1B41HB1N r rGr)rVrWrXrPr{r__annotations__rr`propertyrrrnrrrrrrYr rrr9sn. GZK&M "" &   (#0 r rc:eZdZddZdZeZddddidfdZd dZy) EntityReferenceNcftj||||_d|zdzx|_|_y)Nr4;)r[rPeref nodeValuedata)rOrr]s rrPzEntityReference.__init__s. dJ' %(4Z#%55r ct|tsy|j|jk(xr|j|jk(Sr")r(rrrrs risEqualToEntityReferencez(EntityReference.isEqualToEntityReferences4!_- QVV#H$..AKK*GHr rdrcDt|}|d|jzy)Nrdr3rrs rrnzEntityReference.writexmls  ' "t~~ r c.t|j|SrG)rrrxs rr{zEntityReference.cloneNodestyy&11r rGr)rVrWrXrPrr`rnr{rYr rrrs26 I -M   2r rceZdZddZdZeZy) CharacterDataNcZtj|||x|_x|_|_yrG)r[rPvaluerr)rOrr]s rrPzCharacterData.__init__s% dJ'266 6TYr c4|j|jk(SrG)rrs risEqualToCharacterDataz$CharacterData.isEqualToCharacterDataszzQWW$$r rG)rVrWrXrPrr`rYr rrrs7%+Mr rc,eZdZdZddddidfdZddZy)rz A comment node. rdrcJt|}|j} |d| dy)Nz)r3r) rOr.rhrirjrkrlrmr/vals rrnzComment.writexmls'  'ii DS/r Nc.t|j|SrG)rrrxs rr{zComment.cloneNodest~~v..r r)rVrWrX__doc__rnr{rYr rrrs%  /r rc>eZdZd dZdZd dZddddidfdZd dZy) rNrc@tj|||||_yrG)rrPraw)rOrr]rs rrPz Text.__init__stT:6r cdtj||xr|j|jk(S)z Compare this text to C{text}. If the underlying values and the C{raw} flag are the same, return C{True}, otherwise return C{False}. )rr`rrOras rr`zText.isEqualToNodes) **47QDHH rrs rrnzCDATASection.writexmls-  ' + "t~~  %r r)rVrWrXr{rnrYr rrrs 4   r rc#<Kd} dt|z|dz}w)Nrpr})r))rs r _genprefixr s* A CFl E sceZdZdZy)_Attrz#Support class for getAttributeNode.N)rVrWrXrrYr rrrs)r rceZdZdZdZdZ ddZdZdZdZ dZ dd Z d Z d Z dd Zdd ZdZdZdZdZddddidfdZddZddZy)rrr}Nc tj|||xs| |_||_|s|j }|i|_nA||_|j j D]\} } t| |j | <|rt|j ||_|x|_ x|_ |_ ||_ ||_ ||_y)N)preserve)r[rP preserveCaserr# attributesitemsr@r endTagNamertagName _filename_markposrm) rOrrr]rHmarkposrrrmkrs rrPzElement.__init__s dJ'(?,?.mmoG   DO(DO--/ 11%-a[" 1 -doo UDO9@@@$-$,! "r cb|j||_y|jj|yrG)rlupdate)rOpfxss r addPrefixeszElement.addPrefixes>s% ?? ""DO OO " "4 (r cJ|js|j}||_yrG)rr#r)rOrs rendTagzElement.endTagDs   #))+J$r c"|jrP|j|jk(xr5|jj|jjk(S|j|jk(xr|j|jk(SrG)rrrr#rs risEqualToElementzElement.isEqualToElementIsn   OOq||3 ##%)9)9);; 1<</Rdmmqzz6QRr c|jj|jjk(xrL|j|jk(xr1|j|jk(xrtj ||S)z Compare this element to C{other}. If the C{nodeName}, C{namespace}, C{attributes}, and C{childNodes} are all the same, return C{True}, otherwise return C{False}. )rr#rmrr[r`rs rr`zElement.isEqualToNodePsn MM   !U^^%9%9%; ; 0%//1 05#3#33 0""4/  r c>t|j||j|j|j}|j j |j |r1|jDcgc]}|jd|c}|_|Sg|_|Scc}w)N)r]rmrrr}) rrrmrrrrrr{)rOryrzcloners rr{zElement.cloneNode]s LLnn** 00   0 GKWe5 9WE   "E   Xs.BcJ|jr t||St||SrG)rr$rrs rrzElement.getElementsByTagNamels%   -dD9 9#D$//r cyrrYrRs r hasAttributeszElement.hasAttributesqsr c:|jj||SrG)rget)rOrdefaults rrzElement.getAttributets""411r c||f}||jvr|j|S||jk(r|jj||S|SrG)rrmr)rOnsrrnsks rgetAttributeNSzElement.getAttributeNSwsN4j $// !??3' '  ??&&tW5 5r c8t|j||SrG)rrrs rgetAttributeNodezElement.getAttributeNodesT&&t,d33r c"||j|<yrGr)rOrattrs r setAttributezElement.setAttributes $r c<||jvr|j|=yyrGrrs rremoveAttributezElement.removeAttributes 4?? "% #r c||jvSrGrrs r hasAttributezElement.hasAttributest&&r rdc d}d} d} |js|j|_t|} |jr8|jj } |j D] } | | vs| | = ni} dg}|j| vr||g|z}|jfd}|j}||jk7r|jz|j|vr:||j}|dz|jz|dz|jz}nD|j|d|j|j}n|jd j}t|jjD]Y\}}t|tr7|\} }| |vr|| }ntt }|| | <|J||dz|z|M|J|||[| r;| jD]\} }|s |d |z| | j#|| }n|}| |||j$r| d ||z}|j$D]E}|j| vr|j| vr| |||f|j'|||||||G|j| vr| |||f| |d |d fy|jj)|vr| |d |d fy| dy)a* Serialize this L{Element} to the given stream. @param stream: A file-like object to which this L{Element} will be written. @param nsprefixes: A C{dict} mapping namespace URIs as C{str} to prefixes as C{str}. This defines the prefixes which are already in scope in the document at the point at which this L{Element} exists. This is essentially an implementation detail for namespace support. Applications should not try to use it. @param namespace: The namespace URI as a C{str} which is the default at the point in the document at which this L{Element} exists. This is essentially an implementation detail for namespace support. Applications should not try to use it. ) imgbrhrbasemetalinkparamareainputcolbasefontisindexframe)htmlheadbodynoscriptinsdelh1h2h3h4h5h6scriptuloldlprer" blockquoteaddressrdivfieldsettabletrformobjectrAappletmap)rCr:r;r.r5c0d|dt|dfS)Nrz="r7)rC)_atr_valbexts rz"Element.writexml..stS$fTlC,P'Qr N:xmlnsrdzxmlns:r6z)rrrr3rlcopykeysrrmrsortedrrr(tuplenext genprefixrrrnr#)rOr.rhrirjrkrlrmALLOWSINGLETON BLOCKELEMENTS FORMATNICELYr/ newprefixesrbegin writeattrrprefixjrrkey downprefixes newindentrrKs @rrnzElement.writexmls8  @2   "llDO  ' ??//..0K oo' ($#B (K <<= (6NU*E||Q __  &4>>+E~~+$DNN3Vc\DLL01#c\DOO; T\\"'4>>2!NN    GG 5 5 78 %ID#$&C#'^F!)_F&,KO&&3,,c2&$$ % )//1 5 Fh/4 5   z *&L%L !E( ?? cF*I <<=0T\\\5Qay)*+Iy$|Y  ||},!T6N#$ az3'( ) \\   ! 7 a C() * eHr cdt|jz}|jr|d|jz }|jr|d|jz }|jr|d|jz }|dzS)Nz Element(%sz , attributes=z , filename=z , markpos=r)rrrrr)rOreps rrzElement.__repr__5svT$--00 ?? ]4??"56 6C >> [ 23 3C == Z 01 1CSyr cd|jz}|js |jr|dz }|jr|t|jz }|jr|d|jzz }|js |jr|dz }|jj D] }|d|zz } |j r|d|jzz }|S|dz }|S)Nr5z (z line %s column %srz %s=%rz >...rO)rrrrrrr)rOrbitems rrSzElement.__str__?sDMM! >>T]] 4KC >> 4' 'C == '$--7 7C >>T]] 3JCOO))+ #D 8d? "C #     <$--/ /C  5LC r )NNNNr}rNrrGrT)rVrWrXrrrlrPrrrr`r{rr rrrrrrrnrrSrYr rrrsLOJ #>) % S   0 24%&'  gRr rcVi}|jD]\}}t|||<|SrG)rr@rddrrs r _unescapeDictrhRs2 B 1 1 Ir cDi}|jD] \}}|||< |SrG)rrfs r _reverseDictrjYs. B 11 Ir ceZdZdjZddgddgddgdggdgdgddgdgd gd gd gd gd d gdgdZdddeefdZdZdZe jdZ dZ dZ dZdZdZdZdZdZdZdZy )!MicroDOMParserz#area link br img hr input base metardtrgli)theadtfoottbodycolgroupr)rCtdthr/r.option)rrmrgrnrqrorprrr)rCrsrtr.titlerurr}cg|_ddd}t|}|d|fg|_g|_d|_||_||_|xs| |_||_||_ y)NrN)rNrd) elementstackrjnsstack documents _mddoctypebeExtremelyLenientrr soonClosers laterClosers)rOr|rrr}r~rdrs rrPzMicroDOMParser.__init__xsl4 ( !_D"  "4.(?,?&(r ctt|jD]8}|j| }|jdk(s|j dddk(s8yy)Nr=z xml:spacerdrr}r)rangerrxrr)rOedxels rshouldPreserveSpacez"MicroDOMParser.shouldPreserveSpacesYT../0 C""C4(BzzU"book2&F*&T r c:|jr|jdSyr)rxrRs r _getparentzMicroDOMParser._getparents   $$R( (r z \s*/[/*]\s*c|jrt|jdk(sy|j}t |t rd}|j }|jj|}|r|j}|t|d} td|zjd}t|jdk7ry|j}t |ttfrIg|_|r$|jjt ||jj|yyy#ttf$rYywxYw)Nr}rdz %sr)r|rrrr(rrCOMMENTmatchgroup parseStringr rErrr)rOrrr\oldvalueres r_fixScriptElementz MicroDOMParser._fixScriptElements&&c"--.@A.E  MMO a  FwwHLL&&x0E#CKM2  h 67BB1E1<< A% A!lG45 " MM((f6 $$Q' 6+  /  sD55EEc||_yrG)r{)rOrs r gotDoctypezMicroDOMParser.gotDoctypes !r c |j}|jrt|tr|j}|}|j r |j }|j }||jj|gvr+|j|j|j}t|}|jdd}i}g}|jD]V\} } | jds| jdd} t| dk(r | || d<n| |d<|j!| X|D]} || =|r!|j#}|j%|g}|jD]Q\} } | jdd} t| dk(s'| \} }| dk7s2| |vs7| ||| |f<|j!| S|D]} || =t||||j&|j)|j |j*|jd }t-|}|j/||rO|jddj#}|j%||jj!|||f|j0j!||r|j3||jr+|j|j4vr|j|yyy) NrrrNrMr}rdxml)rrrm)rr|r(rrrr#r~r gotTagEndrhryr startswithrrrrPrrHsaveMarkrrjrrxrr})rOrrrz parentNamemyName namespaces newspaces keysToDeleterr spacenamesksplitpfxtvr revspacesrscopys r gotTagStartzMicroDOMParser.gotTagStarts"  " "z&''BJF##'--/ **..z2>>v~~.*":. \\"%a(   $$& 'DAq||G$WWS!_ z?a'/0Ijm,$%IbM##A& ' A1   #*J   i ( $$& +DAqWWS!_F6{a R% "r cLtj|||jr|jr)|jj |jdyt |j|jddf|jz|jdjzy)Nrr END_OF_FILE) r connectionLostrxr|rzrrErHrr)rOreasons rrzMicroDOMParser.connectionLostTs  v.   &&%%d&7&7&:;$(9(9"(=}M--/*++B/889 r N)rVrWrXrr}r~rPrrrecompilerrrrrrrrrrrrYr rrlrl`s 8==?K4[TlTlf,,,Lwfff&!*L(! )* bjj(G(B"=!~&,+81>'@ r rlc:t|ds t|d}t|i|}t|dd|_|j dt|dr |j |jn8|jd}|r%|j ||jd}|r%|jd|jst|jddd |jrt|jd k(r>|jd}t|ts\td }|j!||}n=td }|jD]}|j!|n|jd}t#|}|j$|_|S) z% Parse HTML or XML readable. readrbrz NrpirzNo top-level Nodes in documentr}r-)ropenrlgetattrrHmakeConnection dataReceivedrprrrzr r|rr(rrrr{r) readableargskwargsmdprrrrdocs rparsercsd 8V $$' $ )& )C8V];CLtx$ **,- MM$    Q  d#At ==q!-MNN  s}}  " a Aa)V_q!A % e$ % MM!  1+C..CK Jr ct|tr'tt|j dg|i|Stt|g|i|S)NzUTF-16)r(r)rrr*)strrs rrrsH"cWRYYx01?D?B??  *t *r **r ct|ddSz' Parse an XML readable object. rr}rr)r)rs rparseXMLrs 11 ==r ct|ddSr)r)rs rparseXMLStringrs r11 ==r c8eZdZdZd dZdZdZdZd dZdZ y) lmxz Easy creation of XML. cHt|tr t|}||_yrG)r(r)rr)rOrs rrPz lmx.__init__s dC 4=D r c8ddk(r tdfdS)Nr_zno private attrsc*jfi|SrG)add)rrrOs rrLz!lmx.__getattr__..sHDHHT0R0r )AttributeErrorrs``r __getattr__zlmx.__getattr__s 7c> !34 400r c<|jj||yrG)rr)rOr^rs r __setitem__zlmx.__setitem__s sC(r c8|jj|SrG)rr)rOr^s r __getitem__zlmx.__getitem__syy%%c**r cVt||}|jj||S)N)r)rrr)rOtxtrnns rr=zlmx.texts% #3  b! r c t|dd}|jj|t|}|j D]\}}|ddk(r|dd}|||<|S)Nrrrr})rrrrr)rOrrnewNodexfrrs rrzlmx.addsj'11E g& \HHJ DAqts{abEBqE  r N)r@)r) rVrWrXrrPrrrr=rrYr rrrs% 1 )+ r r)6r __future__rrwarningsiorr incrementalrrtwisted.python.compatrtwisted.python.utilr twisted.web.suxr r format warningStringwarnDeprecationWarningrr$r3HTML_ESCAPE_CHARSlistREV_HTML_ESCAPE_CHARSreverseXML_ESCAPE_CHARSREV_XML_ESCAPE_CHARSr@rC ExceptionrEr[rrrrrrrrUrrrhrjrlrrrrrrYr rrs"#  1)/1;BBWYB23  m/A>6  & ./$'99,-/) Y 6KKtQtQh2d2<+D+/m/.(6=(6V=( L *M*udup @Y@F$N+>>""r