etree.go 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453
  1. // Copyright 2015-2019 Brett Vickers.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package etree provides XML services through an Element Tree
  5. // abstraction.
  6. package etree
  7. import (
  8. "bufio"
  9. "bytes"
  10. "encoding/xml"
  11. "errors"
  12. "io"
  13. "os"
  14. "sort"
  15. "strings"
  16. )
  17. const (
  18. // NoIndent is used with Indent to disable all indenting.
  19. NoIndent = -1
  20. )
  21. // ErrXML is returned when XML parsing fails due to incorrect formatting.
  22. var ErrXML = errors.New("etree: invalid XML format")
  23. // ReadSettings allow for changing the default behavior of the ReadFrom*
  24. // methods.
  25. type ReadSettings struct {
  26. // CharsetReader to be passed to standard xml.Decoder. Default: nil.
  27. CharsetReader func(charset string, input io.Reader) (io.Reader, error)
  28. // Permissive allows input containing common mistakes such as missing tags
  29. // or attribute values. Default: false.
  30. Permissive bool
  31. // Entity to be passed to standard xml.Decoder. Default: nil.
  32. Entity map[string]string
  33. }
  34. // newReadSettings creates a default ReadSettings record.
  35. func newReadSettings() ReadSettings {
  36. return ReadSettings{
  37. CharsetReader: func(label string, input io.Reader) (io.Reader, error) {
  38. return input, nil
  39. },
  40. Permissive: false,
  41. }
  42. }
  43. // WriteSettings allow for changing the serialization behavior of the WriteTo*
  44. // methods.
  45. type WriteSettings struct {
  46. // CanonicalEndTags forces the production of XML end tags, even for
  47. // elements that have no child elements. Default: false.
  48. CanonicalEndTags bool
  49. // CanonicalText forces the production of XML character references for
  50. // text data characters &, <, and >. If false, XML character references
  51. // are also produced for " and '. Default: false.
  52. CanonicalText bool
  53. // CanonicalAttrVal forces the production of XML character references for
  54. // attribute value characters &, < and ". If false, XML character
  55. // references are also produced for > and '. Default: false.
  56. CanonicalAttrVal bool
  57. // When outputting indented XML, use a carriage return and linefeed
  58. // ("\r\n") as a new-line delimiter instead of just a linefeed ("\n").
  59. // This is useful on Windows-based systems.
  60. UseCRLF bool
  61. }
  62. // newWriteSettings creates a default WriteSettings record.
  63. func newWriteSettings() WriteSettings {
  64. return WriteSettings{
  65. CanonicalEndTags: false,
  66. CanonicalText: false,
  67. CanonicalAttrVal: false,
  68. UseCRLF: false,
  69. }
  70. }
  71. // A Token is an empty interface that represents an Element, CharData,
  72. // Comment, Directive, or ProcInst.
  73. type Token interface {
  74. Parent() *Element
  75. Index() int
  76. dup(parent *Element) Token
  77. setParent(parent *Element)
  78. setIndex(index int)
  79. writeTo(w *bufio.Writer, s *WriteSettings)
  80. }
  81. // A Document is a container holding a complete XML hierarchy. Its embedded
  82. // element contains zero or more children, one of which is usually the root
  83. // element. The embedded element may include other children such as
  84. // processing instructions or BOM CharData tokens.
  85. type Document struct {
  86. Element
  87. ReadSettings ReadSettings
  88. WriteSettings WriteSettings
  89. }
  90. // An Element represents an XML element, its attributes, and its child tokens.
  91. type Element struct {
  92. Space, Tag string // namespace prefix and tag
  93. Attr []Attr // key-value attribute pairs
  94. Child []Token // child tokens (elements, comments, etc.)
  95. parent *Element // parent element
  96. index int // token index in parent's children
  97. }
  98. // An Attr represents a key-value attribute of an XML element.
  99. type Attr struct {
  100. Space, Key string // The attribute's namespace prefix and key
  101. Value string // The attribute value string
  102. element *Element // element containing the attribute
  103. }
  104. // charDataFlags are used with CharData tokens to store additional settings.
  105. type charDataFlags uint8
  106. const (
  107. // The CharData was created by an indent function as whitespace.
  108. whitespaceFlag charDataFlags = 1 << iota
  109. // The CharData contains a CDATA section.
  110. cdataFlag
  111. )
  112. // CharData can be used to represent character data or a CDATA section within
  113. // an XML document.
  114. type CharData struct {
  115. Data string
  116. parent *Element
  117. index int
  118. flags charDataFlags
  119. }
  120. // A Comment represents an XML comment.
  121. type Comment struct {
  122. Data string
  123. parent *Element
  124. index int
  125. }
  126. // A Directive represents an XML directive.
  127. type Directive struct {
  128. Data string
  129. parent *Element
  130. index int
  131. }
  132. // A ProcInst represents an XML processing instruction.
  133. type ProcInst struct {
  134. Target string
  135. Inst string
  136. parent *Element
  137. index int
  138. }
  139. // NewDocument creates an XML document without a root element.
  140. func NewDocument() *Document {
  141. return &Document{
  142. Element{Child: make([]Token, 0)},
  143. newReadSettings(),
  144. newWriteSettings(),
  145. }
  146. }
  147. // Copy returns a recursive, deep copy of the document.
  148. func (d *Document) Copy() *Document {
  149. return &Document{*(d.dup(nil).(*Element)), d.ReadSettings, d.WriteSettings}
  150. }
  151. // Root returns the root element of the document, or nil if there is no root
  152. // element.
  153. func (d *Document) Root() *Element {
  154. for _, t := range d.Child {
  155. if c, ok := t.(*Element); ok {
  156. return c
  157. }
  158. }
  159. return nil
  160. }
  161. // SetRoot replaces the document's root element with e. If the document
  162. // already has a root when this function is called, then the document's
  163. // original root is unbound first. If the element e is bound to another
  164. // document (or to another element within a document), then it is unbound
  165. // first.
  166. func (d *Document) SetRoot(e *Element) {
  167. if e.parent != nil {
  168. e.parent.RemoveChild(e)
  169. }
  170. p := &d.Element
  171. e.setParent(p)
  172. // If there is already a root element, replace it.
  173. for i, t := range p.Child {
  174. if _, ok := t.(*Element); ok {
  175. t.setParent(nil)
  176. t.setIndex(-1)
  177. p.Child[i] = e
  178. e.setIndex(i)
  179. return
  180. }
  181. }
  182. // No existing root element, so add it.
  183. p.addChild(e)
  184. }
  185. // ReadFrom reads XML from the reader r into the document d. It returns the
  186. // number of bytes read and any error encountered.
  187. func (d *Document) ReadFrom(r io.Reader) (n int64, err error) {
  188. return d.Element.readFrom(r, d.ReadSettings)
  189. }
  190. // ReadFromFile reads XML from the string s into the document d.
  191. func (d *Document) ReadFromFile(filename string) error {
  192. f, err := os.Open(filename)
  193. if err != nil {
  194. return err
  195. }
  196. defer f.Close()
  197. _, err = d.ReadFrom(f)
  198. return err
  199. }
  200. // ReadFromBytes reads XML from the byte slice b into the document d.
  201. func (d *Document) ReadFromBytes(b []byte) error {
  202. _, err := d.ReadFrom(bytes.NewReader(b))
  203. return err
  204. }
  205. // ReadFromString reads XML from the string s into the document d.
  206. func (d *Document) ReadFromString(s string) error {
  207. _, err := d.ReadFrom(strings.NewReader(s))
  208. return err
  209. }
  210. // WriteTo serializes an XML document into the writer w. It
  211. // returns the number of bytes written and any error encountered.
  212. func (d *Document) WriteTo(w io.Writer) (n int64, err error) {
  213. cw := newCountWriter(w)
  214. b := bufio.NewWriter(cw)
  215. for _, c := range d.Child {
  216. c.writeTo(b, &d.WriteSettings)
  217. }
  218. err, n = b.Flush(), cw.bytes
  219. return
  220. }
  221. // WriteToFile serializes an XML document into the file named
  222. // filename.
  223. func (d *Document) WriteToFile(filename string) error {
  224. f, err := os.Create(filename)
  225. if err != nil {
  226. return err
  227. }
  228. defer f.Close()
  229. _, err = d.WriteTo(f)
  230. return err
  231. }
  232. // WriteToBytes serializes the XML document into a slice of
  233. // bytes.
  234. func (d *Document) WriteToBytes() (b []byte, err error) {
  235. var buf bytes.Buffer
  236. if _, err = d.WriteTo(&buf); err != nil {
  237. return
  238. }
  239. return buf.Bytes(), nil
  240. }
  241. // WriteToString serializes the XML document into a string.
  242. func (d *Document) WriteToString() (s string, err error) {
  243. var b []byte
  244. if b, err = d.WriteToBytes(); err != nil {
  245. return
  246. }
  247. return string(b), nil
  248. }
  249. type indentFunc func(depth int) string
  250. // Indent modifies the document's element tree by inserting character data
  251. // tokens containing newlines and indentation. The amount of indentation per
  252. // depth level is given as spaces. Pass etree.NoIndent for spaces if you want
  253. // no indentation at all.
  254. func (d *Document) Indent(spaces int) {
  255. var indent indentFunc
  256. switch {
  257. case spaces < 0:
  258. indent = func(depth int) string { return "" }
  259. case d.WriteSettings.UseCRLF == true:
  260. indent = func(depth int) string { return indentCRLF(depth*spaces, indentSpaces) }
  261. default:
  262. indent = func(depth int) string { return indentLF(depth*spaces, indentSpaces) }
  263. }
  264. d.Element.indent(0, indent)
  265. }
  266. // IndentTabs modifies the document's element tree by inserting CharData
  267. // tokens containing newlines and tabs for indentation. One tab is used per
  268. // indentation level.
  269. func (d *Document) IndentTabs() {
  270. var indent indentFunc
  271. switch d.WriteSettings.UseCRLF {
  272. case true:
  273. indent = func(depth int) string { return indentCRLF(depth, indentTabs) }
  274. default:
  275. indent = func(depth int) string { return indentLF(depth, indentTabs) }
  276. }
  277. d.Element.indent(0, indent)
  278. }
  279. // NewElement creates an unparented element with the specified tag. The tag
  280. // may be prefixed by a namespace prefix and a colon.
  281. func NewElement(tag string) *Element {
  282. space, stag := spaceDecompose(tag)
  283. return newElement(space, stag, nil)
  284. }
  285. // newElement is a helper function that creates an element and binds it to
  286. // a parent element if possible.
  287. func newElement(space, tag string, parent *Element) *Element {
  288. e := &Element{
  289. Space: space,
  290. Tag: tag,
  291. Attr: make([]Attr, 0),
  292. Child: make([]Token, 0),
  293. parent: parent,
  294. index: -1,
  295. }
  296. if parent != nil {
  297. parent.addChild(e)
  298. }
  299. return e
  300. }
  301. // Copy creates a recursive, deep copy of the element and all its attributes
  302. // and children. The returned element has no parent but can be parented to a
  303. // another element using AddElement, or to a document using SetRoot.
  304. func (e *Element) Copy() *Element {
  305. return e.dup(nil).(*Element)
  306. }
  307. // FullTag returns the element e's complete tag, including namespace prefix if
  308. // present.
  309. func (e *Element) FullTag() string {
  310. if e.Space == "" {
  311. return e.Tag
  312. }
  313. return e.Space + ":" + e.Tag
  314. }
  315. // NamespaceURI returns the XML namespace URI associated with the element. If
  316. // the element is part of the XML default namespace, NamespaceURI returns the
  317. // empty string.
  318. func (e *Element) NamespaceURI() string {
  319. if e.Space == "" {
  320. return e.findDefaultNamespaceURI()
  321. }
  322. return e.findLocalNamespaceURI(e.Space)
  323. }
  324. // findLocalNamespaceURI finds the namespace URI corresponding to the
  325. // requested prefix.
  326. func (e *Element) findLocalNamespaceURI(prefix string) string {
  327. for _, a := range e.Attr {
  328. if a.Space == "xmlns" && a.Key == prefix {
  329. return a.Value
  330. }
  331. }
  332. if e.parent == nil {
  333. return ""
  334. }
  335. return e.parent.findLocalNamespaceURI(prefix)
  336. }
  337. // findDefaultNamespaceURI finds the default namespace URI of the element.
  338. func (e *Element) findDefaultNamespaceURI() string {
  339. for _, a := range e.Attr {
  340. if a.Space == "" && a.Key == "xmlns" {
  341. return a.Value
  342. }
  343. }
  344. if e.parent == nil {
  345. return ""
  346. }
  347. return e.parent.findDefaultNamespaceURI()
  348. }
  349. // hasText returns true if the element has character data immediately
  350. // folllowing the element's opening tag.
  351. func (e *Element) hasText() bool {
  352. if len(e.Child) == 0 {
  353. return false
  354. }
  355. _, ok := e.Child[0].(*CharData)
  356. return ok
  357. }
  358. // namespacePrefix returns the namespace prefix associated with the element.
  359. func (e *Element) namespacePrefix() string {
  360. return e.Space
  361. }
  362. // name returns the tag associated with the element.
  363. func (e *Element) name() string {
  364. return e.Tag
  365. }
  366. // Text returns all character data immediately following the element's opening
  367. // tag.
  368. func (e *Element) Text() string {
  369. if len(e.Child) == 0 {
  370. return ""
  371. }
  372. text := ""
  373. for _, ch := range e.Child {
  374. if cd, ok := ch.(*CharData); ok {
  375. if text == "" {
  376. text = cd.Data
  377. } else {
  378. text = text + cd.Data
  379. }
  380. } else {
  381. break
  382. }
  383. }
  384. return text
  385. }
  386. // SetText replaces all character data immediately following an element's
  387. // opening tag with the requested string.
  388. func (e *Element) SetText(text string) {
  389. e.replaceText(0, text, 0)
  390. }
  391. // SetCData replaces all character data immediately following an element's
  392. // opening tag with a CDATA section.
  393. func (e *Element) SetCData(text string) {
  394. e.replaceText(0, text, cdataFlag)
  395. }
  396. // Tail returns all character data immediately following the element's end
  397. // tag.
  398. func (e *Element) Tail() string {
  399. if e.Parent() == nil {
  400. return ""
  401. }
  402. p := e.Parent()
  403. i := e.Index()
  404. text := ""
  405. for _, ch := range p.Child[i+1:] {
  406. if cd, ok := ch.(*CharData); ok {
  407. if text == "" {
  408. text = cd.Data
  409. } else {
  410. text = text + cd.Data
  411. }
  412. } else {
  413. break
  414. }
  415. }
  416. return text
  417. }
  418. // SetTail replaces all character data immediately following the element's end
  419. // tag with the requested string.
  420. func (e *Element) SetTail(text string) {
  421. if e.Parent() == nil {
  422. return
  423. }
  424. p := e.Parent()
  425. p.replaceText(e.Index()+1, text, 0)
  426. }
  427. // replaceText is a helper function that replaces a series of chardata tokens
  428. // starting at index i with the requested text.
  429. func (e *Element) replaceText(i int, text string, flags charDataFlags) {
  430. end := e.findTermCharDataIndex(i)
  431. switch {
  432. case end == i:
  433. if text != "" {
  434. // insert a new chardata token at index i
  435. cd := newCharData(text, flags, nil)
  436. e.InsertChildAt(i, cd)
  437. }
  438. case end == i+1:
  439. if text == "" {
  440. // remove the chardata token at index i
  441. e.RemoveChildAt(i)
  442. } else {
  443. // replace the first and only character token at index i
  444. cd := e.Child[i].(*CharData)
  445. cd.Data, cd.flags = text, flags
  446. }
  447. default:
  448. if text == "" {
  449. // remove all chardata tokens starting from index i
  450. copy(e.Child[i:], e.Child[end:])
  451. removed := end - i
  452. e.Child = e.Child[:len(e.Child)-removed]
  453. for j := i; j < len(e.Child); j++ {
  454. e.Child[j].setIndex(j)
  455. }
  456. } else {
  457. // replace the first chardata token at index i and remove all
  458. // subsequent chardata tokens
  459. cd := e.Child[i].(*CharData)
  460. cd.Data, cd.flags = text, flags
  461. copy(e.Child[i+1:], e.Child[end:])
  462. removed := end - (i + 1)
  463. e.Child = e.Child[:len(e.Child)-removed]
  464. for j := i + 1; j < len(e.Child); j++ {
  465. e.Child[j].setIndex(j)
  466. }
  467. }
  468. }
  469. }
  470. // findTermCharDataIndex finds the index of the first child token that isn't
  471. // a CharData token. It starts from the requested start index.
  472. func (e *Element) findTermCharDataIndex(start int) int {
  473. for i := start; i < len(e.Child); i++ {
  474. if _, ok := e.Child[i].(*CharData); !ok {
  475. return i
  476. }
  477. }
  478. return len(e.Child)
  479. }
  480. // CreateElement creates an element with the specified tag and adds it as the
  481. // last child element of the element e. The tag may be prefixed by a namespace
  482. // prefix and a colon.
  483. func (e *Element) CreateElement(tag string) *Element {
  484. space, stag := spaceDecompose(tag)
  485. return newElement(space, stag, e)
  486. }
  487. // AddChild adds the token t as the last child of element e. If token t was
  488. // already the child of another element, it is first removed from its current
  489. // parent element.
  490. func (e *Element) AddChild(t Token) {
  491. if t.Parent() != nil {
  492. t.Parent().RemoveChild(t)
  493. }
  494. t.setParent(e)
  495. e.addChild(t)
  496. }
  497. // InsertChild inserts the token t before e's existing child token ex. If ex
  498. // is nil or ex is not a child of e, then t is added to the end of e's child
  499. // token list. If token t was already the child of another element, it is
  500. // first removed from its current parent element.
  501. //
  502. // Deprecated: InsertChild is deprecated. Use InsertChildAt instead.
  503. func (e *Element) InsertChild(ex Token, t Token) {
  504. if ex == nil || ex.Parent() != e {
  505. e.AddChild(t)
  506. return
  507. }
  508. if t.Parent() != nil {
  509. t.Parent().RemoveChild(t)
  510. }
  511. t.setParent(e)
  512. i := ex.Index()
  513. e.Child = append(e.Child, nil)
  514. copy(e.Child[i+1:], e.Child[i:])
  515. e.Child[i] = t
  516. for j := i; j < len(e.Child); j++ {
  517. e.Child[j].setIndex(j)
  518. }
  519. }
  520. // InsertChildAt inserts the token t into the element e's list of child tokens
  521. // just before the requested index. If the index is greater than or equal to
  522. // the length of the list of child tokens, the token t is added to the end of
  523. // the list.
  524. func (e *Element) InsertChildAt(index int, t Token) {
  525. if index >= len(e.Child) {
  526. e.AddChild(t)
  527. return
  528. }
  529. if t.Parent() != nil {
  530. if t.Parent() == e && t.Index() > index {
  531. index--
  532. }
  533. t.Parent().RemoveChild(t)
  534. }
  535. t.setParent(e)
  536. e.Child = append(e.Child, nil)
  537. copy(e.Child[index+1:], e.Child[index:])
  538. e.Child[index] = t
  539. for j := index; j < len(e.Child); j++ {
  540. e.Child[j].setIndex(j)
  541. }
  542. }
  543. // RemoveChild attempts to remove the token t from element e's list of
  544. // children. If the token t is a child of e, then it is returned. Otherwise,
  545. // nil is returned.
  546. func (e *Element) RemoveChild(t Token) Token {
  547. if t.Parent() != e {
  548. return nil
  549. }
  550. return e.RemoveChildAt(t.Index())
  551. }
  552. // RemoveChildAt removes the index-th child token from the element e. The
  553. // removed child token is returned. If the index is out of bounds, no child is
  554. // removed and nil is returned.
  555. func (e *Element) RemoveChildAt(index int) Token {
  556. if index >= len(e.Child) {
  557. return nil
  558. }
  559. t := e.Child[index]
  560. for j := index + 1; j < len(e.Child); j++ {
  561. e.Child[j].setIndex(j - 1)
  562. }
  563. e.Child = append(e.Child[:index], e.Child[index+1:]...)
  564. t.setIndex(-1)
  565. t.setParent(nil)
  566. return t
  567. }
  568. // ReadFrom reads XML from the reader r and stores the result as a new child
  569. // of element e.
  570. func (e *Element) readFrom(ri io.Reader, settings ReadSettings) (n int64, err error) {
  571. r := newCountReader(ri)
  572. dec := xml.NewDecoder(r)
  573. dec.CharsetReader = settings.CharsetReader
  574. dec.Strict = !settings.Permissive
  575. dec.Entity = settings.Entity
  576. var stack stack
  577. stack.push(e)
  578. for {
  579. t, err := dec.RawToken()
  580. switch {
  581. case err == io.EOF:
  582. return r.bytes, nil
  583. case err != nil:
  584. return r.bytes, err
  585. case stack.empty():
  586. return r.bytes, ErrXML
  587. }
  588. top := stack.peek().(*Element)
  589. switch t := t.(type) {
  590. case xml.StartElement:
  591. e := newElement(t.Name.Space, t.Name.Local, top)
  592. for _, a := range t.Attr {
  593. e.createAttr(a.Name.Space, a.Name.Local, a.Value, e)
  594. }
  595. stack.push(e)
  596. case xml.EndElement:
  597. stack.pop()
  598. case xml.CharData:
  599. data := string(t)
  600. var flags charDataFlags
  601. if isWhitespace(data) {
  602. flags = whitespaceFlag
  603. }
  604. newCharData(data, flags, top)
  605. case xml.Comment:
  606. newComment(string(t), top)
  607. case xml.Directive:
  608. newDirective(string(t), top)
  609. case xml.ProcInst:
  610. newProcInst(t.Target, string(t.Inst), top)
  611. }
  612. }
  613. }
  614. // SelectAttr finds an element attribute matching the requested key and
  615. // returns it if found. Returns nil if no matching attribute is found. The key
  616. // may be prefixed by a namespace prefix and a colon.
  617. func (e *Element) SelectAttr(key string) *Attr {
  618. space, skey := spaceDecompose(key)
  619. for i, a := range e.Attr {
  620. if spaceMatch(space, a.Space) && skey == a.Key {
  621. return &e.Attr[i]
  622. }
  623. }
  624. return nil
  625. }
  626. // SelectAttrValue finds an element attribute matching the requested key and
  627. // returns its value if found. The key may be prefixed by a namespace prefix
  628. // and a colon. If the key is not found, the dflt value is returned instead.
  629. func (e *Element) SelectAttrValue(key, dflt string) string {
  630. space, skey := spaceDecompose(key)
  631. for _, a := range e.Attr {
  632. if spaceMatch(space, a.Space) && skey == a.Key {
  633. return a.Value
  634. }
  635. }
  636. return dflt
  637. }
  638. // ChildElements returns all elements that are children of element e.
  639. func (e *Element) ChildElements() []*Element {
  640. var elements []*Element
  641. for _, t := range e.Child {
  642. if c, ok := t.(*Element); ok {
  643. elements = append(elements, c)
  644. }
  645. }
  646. return elements
  647. }
  648. // SelectElement returns the first child element with the given tag. The tag
  649. // may be prefixed by a namespace prefix and a colon. Returns nil if no
  650. // element with a matching tag was found.
  651. func (e *Element) SelectElement(tag string) *Element {
  652. space, stag := spaceDecompose(tag)
  653. for _, t := range e.Child {
  654. if c, ok := t.(*Element); ok && spaceMatch(space, c.Space) && stag == c.Tag {
  655. return c
  656. }
  657. }
  658. return nil
  659. }
  660. // SelectElements returns a slice of all child elements with the given tag.
  661. // The tag may be prefixed by a namespace prefix and a colon.
  662. func (e *Element) SelectElements(tag string) []*Element {
  663. space, stag := spaceDecompose(tag)
  664. var elements []*Element
  665. for _, t := range e.Child {
  666. if c, ok := t.(*Element); ok && spaceMatch(space, c.Space) && stag == c.Tag {
  667. elements = append(elements, c)
  668. }
  669. }
  670. return elements
  671. }
  672. // FindElement returns the first element matched by the XPath-like path
  673. // string. Returns nil if no element is found using the path. Panics if an
  674. // invalid path string is supplied.
  675. func (e *Element) FindElement(path string) *Element {
  676. return e.FindElementPath(MustCompilePath(path))
  677. }
  678. // FindElementPath returns the first element matched by the XPath-like path
  679. // string. Returns nil if no element is found using the path.
  680. func (e *Element) FindElementPath(path Path) *Element {
  681. p := newPather()
  682. elements := p.traverse(e, path)
  683. switch {
  684. case len(elements) > 0:
  685. return elements[0]
  686. default:
  687. return nil
  688. }
  689. }
  690. // FindElements returns a slice of elements matched by the XPath-like path
  691. // string. Panics if an invalid path string is supplied.
  692. func (e *Element) FindElements(path string) []*Element {
  693. return e.FindElementsPath(MustCompilePath(path))
  694. }
  695. // FindElementsPath returns a slice of elements matched by the Path object.
  696. func (e *Element) FindElementsPath(path Path) []*Element {
  697. p := newPather()
  698. return p.traverse(e, path)
  699. }
  700. // GetPath returns the absolute path of the element.
  701. func (e *Element) GetPath() string {
  702. path := []string{}
  703. for seg := e; seg != nil; seg = seg.Parent() {
  704. if seg.Tag != "" {
  705. path = append(path, seg.Tag)
  706. }
  707. }
  708. // Reverse the path.
  709. for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 {
  710. path[i], path[j] = path[j], path[i]
  711. }
  712. return "/" + strings.Join(path, "/")
  713. }
  714. // GetRelativePath returns the path of the element relative to the source
  715. // element. If the two elements are not part of the same element tree, then
  716. // GetRelativePath returns the empty string.
  717. func (e *Element) GetRelativePath(source *Element) string {
  718. var path []*Element
  719. if source == nil {
  720. return ""
  721. }
  722. // Build a reverse path from the element toward the root. Stop if the
  723. // source element is encountered.
  724. var seg *Element
  725. for seg = e; seg != nil && seg != source; seg = seg.Parent() {
  726. path = append(path, seg)
  727. }
  728. // If we found the source element, reverse the path and compose the
  729. // string.
  730. if seg == source {
  731. if len(path) == 0 {
  732. return "."
  733. }
  734. parts := []string{}
  735. for i := len(path) - 1; i >= 0; i-- {
  736. parts = append(parts, path[i].Tag)
  737. }
  738. return "./" + strings.Join(parts, "/")
  739. }
  740. // The source wasn't encountered, so climb from the source element toward
  741. // the root of the tree until an element in the reversed path is
  742. // encountered.
  743. findPathIndex := func(e *Element, path []*Element) int {
  744. for i, ee := range path {
  745. if e == ee {
  746. return i
  747. }
  748. }
  749. return -1
  750. }
  751. climb := 0
  752. for seg = source; seg != nil; seg = seg.Parent() {
  753. i := findPathIndex(seg, path)
  754. if i >= 0 {
  755. path = path[:i] // truncate at found segment
  756. break
  757. }
  758. climb++
  759. }
  760. // No element in the reversed path was encountered, so the two elements
  761. // must not be part of the same tree.
  762. if seg == nil {
  763. return ""
  764. }
  765. // Reverse the (possibly truncated) path and prepend ".." segments to
  766. // climb.
  767. parts := []string{}
  768. for i := 0; i < climb; i++ {
  769. parts = append(parts, "..")
  770. }
  771. for i := len(path) - 1; i >= 0; i-- {
  772. parts = append(parts, path[i].Tag)
  773. }
  774. return strings.Join(parts, "/")
  775. }
  776. // indent recursively inserts proper indentation between an
  777. // XML element's child tokens.
  778. func (e *Element) indent(depth int, indent indentFunc) {
  779. e.stripIndent()
  780. n := len(e.Child)
  781. if n == 0 {
  782. return
  783. }
  784. oldChild := e.Child
  785. e.Child = make([]Token, 0, n*2+1)
  786. isCharData, firstNonCharData := false, true
  787. for _, c := range oldChild {
  788. // Insert NL+indent before child if it's not character data.
  789. // Exceptions: when it's the first non-character-data child, or when
  790. // the child is at root depth.
  791. _, isCharData = c.(*CharData)
  792. if !isCharData {
  793. if !firstNonCharData || depth > 0 {
  794. s := indent(depth)
  795. if s != "" {
  796. newCharData(s, whitespaceFlag, e)
  797. }
  798. }
  799. firstNonCharData = false
  800. }
  801. e.addChild(c)
  802. // Recursively process child elements.
  803. if ce, ok := c.(*Element); ok {
  804. ce.indent(depth+1, indent)
  805. }
  806. }
  807. // Insert NL+indent before the last child.
  808. if !isCharData {
  809. if !firstNonCharData || depth > 0 {
  810. s := indent(depth - 1)
  811. if s != "" {
  812. newCharData(s, whitespaceFlag, e)
  813. }
  814. }
  815. }
  816. }
  817. // stripIndent removes any previously inserted indentation.
  818. func (e *Element) stripIndent() {
  819. // Count the number of non-indent child tokens
  820. n := len(e.Child)
  821. for _, c := range e.Child {
  822. if cd, ok := c.(*CharData); ok && cd.IsWhitespace() {
  823. n--
  824. }
  825. }
  826. if n == len(e.Child) {
  827. return
  828. }
  829. // Strip out indent CharData
  830. newChild := make([]Token, n)
  831. j := 0
  832. for _, c := range e.Child {
  833. if cd, ok := c.(*CharData); ok && cd.IsWhitespace() {
  834. continue
  835. }
  836. newChild[j] = c
  837. newChild[j].setIndex(j)
  838. j++
  839. }
  840. e.Child = newChild
  841. }
  842. // dup duplicates the element.
  843. func (e *Element) dup(parent *Element) Token {
  844. ne := &Element{
  845. Space: e.Space,
  846. Tag: e.Tag,
  847. Attr: make([]Attr, len(e.Attr)),
  848. Child: make([]Token, len(e.Child)),
  849. parent: parent,
  850. index: e.index,
  851. }
  852. for i, t := range e.Child {
  853. ne.Child[i] = t.dup(ne)
  854. }
  855. for i, a := range e.Attr {
  856. ne.Attr[i] = a
  857. }
  858. return ne
  859. }
  860. // Parent returns the element token's parent element, or nil if it has no
  861. // parent.
  862. func (e *Element) Parent() *Element {
  863. return e.parent
  864. }
  865. // Index returns the index of this element within its parent element's
  866. // list of child tokens. If this element has no parent element, the index
  867. // is -1.
  868. func (e *Element) Index() int {
  869. return e.index
  870. }
  871. // setParent replaces the element token's parent.
  872. func (e *Element) setParent(parent *Element) {
  873. e.parent = parent
  874. }
  875. // setIndex sets the element token's index within its parent's Child slice.
  876. func (e *Element) setIndex(index int) {
  877. e.index = index
  878. }
  879. // writeTo serializes the element to the writer w.
  880. func (e *Element) writeTo(w *bufio.Writer, s *WriteSettings) {
  881. w.WriteByte('<')
  882. w.WriteString(e.FullTag())
  883. for _, a := range e.Attr {
  884. w.WriteByte(' ')
  885. a.writeTo(w, s)
  886. }
  887. if len(e.Child) > 0 {
  888. w.WriteString(">")
  889. for _, c := range e.Child {
  890. c.writeTo(w, s)
  891. }
  892. w.Write([]byte{'<', '/'})
  893. w.WriteString(e.FullTag())
  894. w.WriteByte('>')
  895. } else {
  896. if s.CanonicalEndTags {
  897. w.Write([]byte{'>', '<', '/'})
  898. w.WriteString(e.FullTag())
  899. w.WriteByte('>')
  900. } else {
  901. w.Write([]byte{'/', '>'})
  902. }
  903. }
  904. }
  905. // addChild adds a child token to the element e.
  906. func (e *Element) addChild(t Token) {
  907. t.setIndex(len(e.Child))
  908. e.Child = append(e.Child, t)
  909. }
  910. // CreateAttr creates an attribute and adds it to element e. The key may be
  911. // prefixed by a namespace prefix and a colon. If an attribute with the key
  912. // already exists, its value is replaced.
  913. func (e *Element) CreateAttr(key, value string) *Attr {
  914. space, skey := spaceDecompose(key)
  915. return e.createAttr(space, skey, value, e)
  916. }
  917. // createAttr is a helper function that creates attributes.
  918. func (e *Element) createAttr(space, key, value string, parent *Element) *Attr {
  919. for i, a := range e.Attr {
  920. if space == a.Space && key == a.Key {
  921. e.Attr[i].Value = value
  922. return &e.Attr[i]
  923. }
  924. }
  925. a := Attr{
  926. Space: space,
  927. Key: key,
  928. Value: value,
  929. element: parent,
  930. }
  931. e.Attr = append(e.Attr, a)
  932. return &e.Attr[len(e.Attr)-1]
  933. }
  934. // RemoveAttr removes and returns a copy of the first attribute of the element
  935. // whose key matches the given key. The key may be prefixed by a namespace
  936. // prefix and a colon. If a matching attribute does not exist, nil is
  937. // returned.
  938. func (e *Element) RemoveAttr(key string) *Attr {
  939. space, skey := spaceDecompose(key)
  940. for i, a := range e.Attr {
  941. if space == a.Space && skey == a.Key {
  942. e.Attr = append(e.Attr[0:i], e.Attr[i+1:]...)
  943. return &Attr{
  944. Space: a.Space,
  945. Key: a.Key,
  946. Value: a.Value,
  947. element: nil,
  948. }
  949. }
  950. }
  951. return nil
  952. }
  953. // SortAttrs sorts the element's attributes lexicographically by key.
  954. func (e *Element) SortAttrs() {
  955. sort.Sort(byAttr(e.Attr))
  956. }
  957. type byAttr []Attr
  958. func (a byAttr) Len() int {
  959. return len(a)
  960. }
  961. func (a byAttr) Swap(i, j int) {
  962. a[i], a[j] = a[j], a[i]
  963. }
  964. func (a byAttr) Less(i, j int) bool {
  965. sp := strings.Compare(a[i].Space, a[j].Space)
  966. if sp == 0 {
  967. return strings.Compare(a[i].Key, a[j].Key) < 0
  968. }
  969. return sp < 0
  970. }
  971. // FullKey returns the attribute a's complete key, including namespace prefix
  972. // if present.
  973. func (a *Attr) FullKey() string {
  974. if a.Space == "" {
  975. return a.Key
  976. }
  977. return a.Space + ":" + a.Key
  978. }
  979. // Element returns the element containing the attribute.
  980. func (a *Attr) Element() *Element {
  981. return a.element
  982. }
  983. // NamespaceURI returns the XML namespace URI associated with the attribute.
  984. // If the element is part of the XML default namespace, NamespaceURI returns
  985. // the empty string.
  986. func (a *Attr) NamespaceURI() string {
  987. return a.element.NamespaceURI()
  988. }
  989. // writeTo serializes the attribute to the writer.
  990. func (a *Attr) writeTo(w *bufio.Writer, s *WriteSettings) {
  991. w.WriteString(a.FullKey())
  992. w.WriteString(`="`)
  993. var m escapeMode
  994. if s.CanonicalAttrVal {
  995. m = escapeCanonicalAttr
  996. } else {
  997. m = escapeNormal
  998. }
  999. escapeString(w, a.Value, m)
  1000. w.WriteByte('"')
  1001. }
  1002. // NewText creates a parentless CharData token containing character data.
  1003. func NewText(text string) *CharData {
  1004. return newCharData(text, 0, nil)
  1005. }
  1006. // NewCData creates a parentless XML character CDATA section.
  1007. func NewCData(data string) *CharData {
  1008. return newCharData(data, cdataFlag, nil)
  1009. }
  1010. // NewCharData creates a parentless CharData token containing character data.
  1011. //
  1012. // Deprecated: NewCharData is deprecated. Instead, use NewText, which does the
  1013. // same thing.
  1014. func NewCharData(data string) *CharData {
  1015. return newCharData(data, 0, nil)
  1016. }
  1017. // newCharData creates a character data token and binds it to a parent
  1018. // element. If parent is nil, the CharData token remains unbound.
  1019. func newCharData(data string, flags charDataFlags, parent *Element) *CharData {
  1020. c := &CharData{
  1021. Data: data,
  1022. parent: parent,
  1023. index: -1,
  1024. flags: flags,
  1025. }
  1026. if parent != nil {
  1027. parent.addChild(c)
  1028. }
  1029. return c
  1030. }
  1031. // CreateText creates a CharData token containing character data and adds it
  1032. // as a child of element e.
  1033. func (e *Element) CreateText(text string) *CharData {
  1034. return newCharData(text, 0, e)
  1035. }
  1036. // CreateCData creates a CharData token containing a CDATA section and adds it
  1037. // as a child of element e.
  1038. func (e *Element) CreateCData(data string) *CharData {
  1039. return newCharData(data, cdataFlag, e)
  1040. }
  1041. // CreateCharData creates a CharData token containing character data and adds
  1042. // it as a child of element e.
  1043. //
  1044. // Deprecated: CreateCharData is deprecated. Instead, use CreateText, which
  1045. // does the same thing.
  1046. func (e *Element) CreateCharData(data string) *CharData {
  1047. return newCharData(data, 0, e)
  1048. }
  1049. // dup duplicates the character data.
  1050. func (c *CharData) dup(parent *Element) Token {
  1051. return &CharData{
  1052. Data: c.Data,
  1053. flags: c.flags,
  1054. parent: parent,
  1055. index: c.index,
  1056. }
  1057. }
  1058. // IsCData returns true if the character data token is to be encoded as a
  1059. // CDATA section.
  1060. func (c *CharData) IsCData() bool {
  1061. return (c.flags & cdataFlag) != 0
  1062. }
  1063. // IsWhitespace returns true if the character data token was created by one of
  1064. // the document Indent methods to contain only whitespace.
  1065. func (c *CharData) IsWhitespace() bool {
  1066. return (c.flags & whitespaceFlag) != 0
  1067. }
  1068. // Parent returns the character data token's parent element, or nil if it has
  1069. // no parent.
  1070. func (c *CharData) Parent() *Element {
  1071. return c.parent
  1072. }
  1073. // Index returns the index of this CharData token within its parent element's
  1074. // list of child tokens. If this CharData token has no parent element, the
  1075. // index is -1.
  1076. func (c *CharData) Index() int {
  1077. return c.index
  1078. }
  1079. // setParent replaces the character data token's parent.
  1080. func (c *CharData) setParent(parent *Element) {
  1081. c.parent = parent
  1082. }
  1083. // setIndex sets the CharData token's index within its parent element's Child
  1084. // slice.
  1085. func (c *CharData) setIndex(index int) {
  1086. c.index = index
  1087. }
  1088. // writeTo serializes character data to the writer.
  1089. func (c *CharData) writeTo(w *bufio.Writer, s *WriteSettings) {
  1090. if c.IsCData() {
  1091. w.WriteString(`<![CDATA[`)
  1092. w.WriteString(c.Data)
  1093. w.WriteString(`]]>`)
  1094. } else {
  1095. var m escapeMode
  1096. if s.CanonicalText {
  1097. m = escapeCanonicalText
  1098. } else {
  1099. m = escapeNormal
  1100. }
  1101. escapeString(w, c.Data, m)
  1102. }
  1103. }
  1104. // NewComment creates a parentless XML comment.
  1105. func NewComment(comment string) *Comment {
  1106. return newComment(comment, nil)
  1107. }
  1108. // NewComment creates an XML comment and binds it to a parent element. If
  1109. // parent is nil, the Comment remains unbound.
  1110. func newComment(comment string, parent *Element) *Comment {
  1111. c := &Comment{
  1112. Data: comment,
  1113. parent: parent,
  1114. index: -1,
  1115. }
  1116. if parent != nil {
  1117. parent.addChild(c)
  1118. }
  1119. return c
  1120. }
  1121. // CreateComment creates an XML comment and adds it as a child of element e.
  1122. func (e *Element) CreateComment(comment string) *Comment {
  1123. return newComment(comment, e)
  1124. }
  1125. // dup duplicates the comment.
  1126. func (c *Comment) dup(parent *Element) Token {
  1127. return &Comment{
  1128. Data: c.Data,
  1129. parent: parent,
  1130. index: c.index,
  1131. }
  1132. }
  1133. // Parent returns comment token's parent element, or nil if it has no parent.
  1134. func (c *Comment) Parent() *Element {
  1135. return c.parent
  1136. }
  1137. // Index returns the index of this Comment token within its parent element's
  1138. // list of child tokens. If this Comment token has no parent element, the
  1139. // index is -1.
  1140. func (c *Comment) Index() int {
  1141. return c.index
  1142. }
  1143. // setParent replaces the comment token's parent.
  1144. func (c *Comment) setParent(parent *Element) {
  1145. c.parent = parent
  1146. }
  1147. // setIndex sets the Comment token's index within its parent element's Child
  1148. // slice.
  1149. func (c *Comment) setIndex(index int) {
  1150. c.index = index
  1151. }
  1152. // writeTo serialies the comment to the writer.
  1153. func (c *Comment) writeTo(w *bufio.Writer, s *WriteSettings) {
  1154. w.WriteString("<!--")
  1155. w.WriteString(c.Data)
  1156. w.WriteString("-->")
  1157. }
  1158. // NewDirective creates a parentless XML directive.
  1159. func NewDirective(data string) *Directive {
  1160. return newDirective(data, nil)
  1161. }
  1162. // newDirective creates an XML directive and binds it to a parent element. If
  1163. // parent is nil, the Directive remains unbound.
  1164. func newDirective(data string, parent *Element) *Directive {
  1165. d := &Directive{
  1166. Data: data,
  1167. parent: parent,
  1168. index: -1,
  1169. }
  1170. if parent != nil {
  1171. parent.addChild(d)
  1172. }
  1173. return d
  1174. }
  1175. // CreateDirective creates an XML directive and adds it as the last child of
  1176. // element e.
  1177. func (e *Element) CreateDirective(data string) *Directive {
  1178. return newDirective(data, e)
  1179. }
  1180. // dup duplicates the directive.
  1181. func (d *Directive) dup(parent *Element) Token {
  1182. return &Directive{
  1183. Data: d.Data,
  1184. parent: parent,
  1185. index: d.index,
  1186. }
  1187. }
  1188. // Parent returns directive token's parent element, or nil if it has no
  1189. // parent.
  1190. func (d *Directive) Parent() *Element {
  1191. return d.parent
  1192. }
  1193. // Index returns the index of this Directive token within its parent element's
  1194. // list of child tokens. If this Directive token has no parent element, the
  1195. // index is -1.
  1196. func (d *Directive) Index() int {
  1197. return d.index
  1198. }
  1199. // setParent replaces the directive token's parent.
  1200. func (d *Directive) setParent(parent *Element) {
  1201. d.parent = parent
  1202. }
  1203. // setIndex sets the Directive token's index within its parent element's Child
  1204. // slice.
  1205. func (d *Directive) setIndex(index int) {
  1206. d.index = index
  1207. }
  1208. // writeTo serializes the XML directive to the writer.
  1209. func (d *Directive) writeTo(w *bufio.Writer, s *WriteSettings) {
  1210. w.WriteString("<!")
  1211. w.WriteString(d.Data)
  1212. w.WriteString(">")
  1213. }
  1214. // NewProcInst creates a parentless XML processing instruction.
  1215. func NewProcInst(target, inst string) *ProcInst {
  1216. return newProcInst(target, inst, nil)
  1217. }
  1218. // newProcInst creates an XML processing instruction and binds it to a parent
  1219. // element. If parent is nil, the ProcInst remains unbound.
  1220. func newProcInst(target, inst string, parent *Element) *ProcInst {
  1221. p := &ProcInst{
  1222. Target: target,
  1223. Inst: inst,
  1224. parent: parent,
  1225. index: -1,
  1226. }
  1227. if parent != nil {
  1228. parent.addChild(p)
  1229. }
  1230. return p
  1231. }
  1232. // CreateProcInst creates a processing instruction and adds it as a child of
  1233. // element e.
  1234. func (e *Element) CreateProcInst(target, inst string) *ProcInst {
  1235. return newProcInst(target, inst, e)
  1236. }
  1237. // dup duplicates the procinst.
  1238. func (p *ProcInst) dup(parent *Element) Token {
  1239. return &ProcInst{
  1240. Target: p.Target,
  1241. Inst: p.Inst,
  1242. parent: parent,
  1243. index: p.index,
  1244. }
  1245. }
  1246. // Parent returns processing instruction token's parent element, or nil if it
  1247. // has no parent.
  1248. func (p *ProcInst) Parent() *Element {
  1249. return p.parent
  1250. }
  1251. // Index returns the index of this ProcInst token within its parent element's
  1252. // list of child tokens. If this ProcInst token has no parent element, the
  1253. // index is -1.
  1254. func (p *ProcInst) Index() int {
  1255. return p.index
  1256. }
  1257. // setParent replaces the processing instruction token's parent.
  1258. func (p *ProcInst) setParent(parent *Element) {
  1259. p.parent = parent
  1260. }
  1261. // setIndex sets the processing instruction token's index within its parent
  1262. // element's Child slice.
  1263. func (p *ProcInst) setIndex(index int) {
  1264. p.index = index
  1265. }
  1266. // writeTo serializes the processing instruction to the writer.
  1267. func (p *ProcInst) writeTo(w *bufio.Writer, s *WriteSettings) {
  1268. w.WriteString("<?")
  1269. w.WriteString(p.Target)
  1270. if p.Inst != "" {
  1271. w.WriteByte(' ')
  1272. w.WriteString(p.Inst)
  1273. }
  1274. w.WriteString("?>")
  1275. }