深入探讨DTD在XML命名空间中的局限性及其带来的挑战

引言:XML命名空间与DTD的演进背景
XML(可扩展标记语言)作为一种灵活的数据交换格式,自1998年正式推荐标准(REC)发布以来,已成为现代计算生态系统的基石。然而,随着XML在复杂场景中的应用扩展,特别是多来源数据集成的需求日益增长,XML命名空间(Namespaces in XML)于1999年被引入,以解决元素和属性名称冲突的问题。命名空间通过URI(统一资源标识符)来限定元素和属性,例如

,允许不同来源的XML片段无缝合并。
文档类型定义(DTD,Document Type Definition)作为XML最早的验证机制,起源于SGML时代,用于定义元素结构、属性类型和实体。它在早期XML应用中扮演了关键角色,但当XML命名空间出现时,DTD的设计并未充分预见其复杂性。这导致了DTD在处理命名空间时的诸多局限性,这些局限性不仅影响了验证的准确性,还带来了互操作性和维护性的挑战。本文将深入剖析DTD在XML命名空间中的核心局限性,通过详细解释、示例和实际影响,帮助读者理解这些问题,并探讨其对现代XML生态的冲击。
我们将从DTD的基本原理入手,逐步展开讨论,确保每个部分都有清晰的主题句和支持细节。如果您是XML开发者或数据架构师,这篇文章将提供实用的洞见,帮助您在设计XML Schema时避免潜在陷阱。
DTD的基本原理及其在XML中的作用
DTD的核心功能概述
DTD是一种声明性语言,用于定义XML文档的结构和约束。它通过元素声明、属性列表、实体和NOTATION来描述文档的有效性。例如,一个简单的DTD可以指定一个文档必须包含特定的元素序列,并限制属性值。
DTD的语法相对简洁,通常嵌入在XML文档的DOCTYPE声明中,或作为外部文件引用。其主要优势在于轻量级和广泛支持——几乎所有XML解析器都原生支持DTD验证,包括浏览器和服务器端工具。
然而,DTD的局限性在于其静态性和缺乏命名空间感知能力。在命名空间引入之前,DTD假设所有元素和属性都在一个全局命名空间中。这在简单文档中有效,但当XML融合多个来源时,问题便显现出来。
DTD在命名空间出现前的典型用法
考虑一个无命名空间的XML文档,描述一本书的目录:





]>

XML Basics


Introduction
This is the first chapter.



在这个例子中,DTD明确指定了元素的嵌套关系和内容模型。验证过程简单:解析器检查文档是否符合DTD规则。如果添加一个未声明的元素,如

,验证将失败。
但当引入命名空间时,这种简单性被打破。命名空间允许元素带有前缀(如
bk:book
),并关联到特定URI。这使得DTD的声明变得模糊,因为DTD无法直接引用这些URI或前缀。
DTD在XML命名空间中的核心局限性
1. 缺乏对命名空间URI的直接支持
主题句
:DTD无法直接声明或验证元素和属性所属的命名空间URI,这是其最根本的局限性。
支持细节
:在XML命名空间规范中,元素通过前缀(如
bk
)绑定到URI(如
http://example.com/book
)。例如:

My Book

DTD的元素声明(如

)不包含URI信息。它只匹配本地名称(local name)”book”,忽略命名空间。这意味着,如果两个不同的命名空间都有一个”book”元素,DTD无法区分它们。验证器可能会错误地接受或拒绝文档,导致数据污染。
实际影响
:在企业集成中,假设您从供应商A(命名空间
http://vendorA.com
)和供应商B(命名空间
http://vendorB.com
)合并XML数据。两者都使用 元素,但结构不同。DTD无法指定”仅验证vendorA的product”,从而造成验证失败或不一致。
示例扩展
:考虑以下DTD和XML:


]>

Widget A
Widget B

验证器会将两个
product
视为相同,导致如果DTD期望特定结构时出错。没有机制来声明

,因为DTD语法不支持前缀或URI。
2. 无法处理带前缀的元素和属性
主题句
:DTD的元素和属性声明不识别XML前缀,导致在命名空间感知的文档中声明无效。
支持细节
:XML命名空间规范允许前缀(如
xml:lang
)来避免歧义,但DTD的声明语法仅限于无前缀的名称。尝试在DTD中使用前缀(如

)是无效的,会导致解析错误。这迫使开发者在DTD中声明”裸”元素,然后在XML中使用前缀,但这破坏了验证的精确性。
此外,属性也有类似问题。属性可以有命名空间(如
xml:space=”preserve”
),但DTD的属性列表(
ATTLIST
)无法指定命名空间。例如:

这只能匹配无命名空间的
lang
属性,无法处理
ns:lang
。
实际影响
:在Web服务中,SOAP消息常使用命名空间来区分头部和主体。如果使用DTD验证,SOAP的

和

无法被正确约束,导致安全漏洞,如意外接受无效消息。
示例扩展
:假设一个文档使用命名空间
http://www.w3.org/1999/xhtml
的XHTML片段:

Hello



如果DTD定义为:



验证通过。但如果添加前缀:

Hello

DTD无法声明
xhtml:html
,验证失败。开发者必须移除前缀或使用无命名空间的DTD,这违背了命名空间的初衷。
3. 内容模型中的命名空间冲突
主题句
:DTD的内容模型(如序列、选择)在命名空间环境中无法精确指定元素来源,导致歧义和验证不准确。
支持细节
:DTD的内容模型使用
|
(选择)和
,
(序列)来定义结构,例如

。在命名空间中,如果
title
来自不同URI,模型无法区分。这源于DTD的”平面”设计:它不支持命名空间感知的模式匹配。
更严重的是,当混合命名空间时,内容模型可能意外匹配错误的元素。例如,一个DTD期望
<br /> 作为子元素,但文档中可能有<br /> <ns1:title><br /> 和<br /> <ns2:title><br /> ,两者都满足本地名称匹配,但语义不同。<br /> 实际影响<br /> :在科学数据交换中,如化学标记语言(CML)和数学标记语言(MathML)的混合,DTD无法确保<br /> <m:math><br /> 元素仅包含MathML内容,而非CML的同名元素。这可能导致计算错误或数据不一致。<br /> 示例扩展<br /> :考虑一个混合文档:<br /> <!DOCTYPE mixed [ <!ELEMENT mixed (title, content)><br /> <!ELEMENT title (#PCDATA)><br /> <!ELEMENT content (para | list)><br /> <!ELEMENT para (#PCDATA)><br /> <!ELEMENT list (item+)><br /> <!ELEMENT item (#PCDATA)><br /> ]><br /> <mixed xmlns:doc="http://doc.org" xmlns:math="http://w3.org/math"><br /> <doc:title>Document Title</doc:title><br /> <content> <para>Some text.</para> <math:math><mi>x</mi></math:math> <!-- 这里math:math不符合content模型,但本地名称匹配para? --><br /> </content><br /> </mixed><br /> 验证器可能接受<br /> <math:math><br /> 作为<br /> para<br /> 的替代(如果忽略命名空间),但实际上它应被拒绝。没有机制在DTD中指定<br /> content<br /> 仅接受特定命名空间的元素。<br /> 4. 实体和符号的命名空间问题<br /> 主题句<br /> :DTD的实体引用和符号声明在命名空间中不兼容,导致外部资源解析失败。<br /> 支持细节<br /> :DTD允许定义实体(如<br /> <!ENTITY ent "value"><br /> )和符号(<br /> <!NOTATION ...><br /> ),用于引用外部文件或数据格式。但在命名空间中,实体名称无法绑定到URI,导致在多命名空间文档中实体引用歧义。例如,<br /> &ent;<br /> 在不同上下文中可能指向不同资源。<br /> 此外,参数实体(用于DTD内部)在命名空间感知的外部DTD中难以管理,因为它们不携带命名空间信息。<br /> 实际影响<br /> :在内容管理系统中,实体常用于嵌入图像或脚本。如果文档使用命名空间,实体可能解析到错误的URI,导致安全风险(如XSS攻击)或资源加载失败。<br /> 示例扩展<br /> :<br /> <!DOCTYPE root [ <!ENTITY logo SYSTEM "logo.png" NDATA png><br /> <!NOTATION png SYSTEM "image/png"><br /> ]><br /> <root xmlns="http://example.com"><br /> <image src="&logo;"/><br /> </root><br /> 如果<br /> <image><br /> 在另一个命名空间中,实体引用仍工作,但无法指定”仅在此命名空间中使用此实体”。在多命名空间场景下,这可能导致实体被误用。<br /> 这些局限性带来的挑战<br /> 互操作性挑战<br /> DTD的命名空间局限性导致不同系统间的XML交换困难。例如,在B2B集成中,供应商可能使用不同命名空间的相同元素名。DTD验证无法确保兼容性,迫使开发者使用自定义解析器或后处理脚本。这增加了开发成本,并降低了系统的可扩展性。<br /> 维护性和可扩展性挑战<br /> 随着XML Schema(XSD)的出现,DTD的静态声明变得过时。修改DTD以适应新命名空间需要重写整个定义,而非增量更新。这在大型项目中(如企业级数据仓库)会导致版本控制问题:旧DTD可能无法验证新命名空间文档,反之亦然。<br /> 安全和准确性挑战<br /> 不准确的验证可能引入安全漏洞。例如,在XML签名(XML Signature)中,命名空间用于区分签名元素。如果DTD忽略命名空间,攻击者可能注入伪造元素,绕过验证。此外,在数据准确性上,如医疗XML(HL7标准),命名空间错误可能导致临床数据误解析。<br /> 性能挑战<br /> 虽然DTD解析快速,但其在命名空间中的不精确性可能导致额外的验证步骤(如手动命名空间检查),增加处理开销。在高吞吐量系统中,这会放大延迟。<br /> 现代替代方案:XML Schema (XSD) 如何解决这些问题<br /> XSD的命名空间支持<br /> XML Schema于2001年成为W3C推荐标准,专为解决DTD的局限性而设计。XSD使用XML语法,支持目标命名空间声明:<br /> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/book" xmlns:bk="http://example.com/book"><br /> <xs:element name="book" type="bk:bookType"/><br /> <xs:complexType name="bookType"><br /> <xs:sequence><br /> <xs:element name="title" type="xs:string"/><br /> </xs:sequence><br /> </xs:complexType><br /> </xs:schema><br /> XSD允许精确引用命名空间元素,如<br /> <xs:element ref="bk:title"/><br /> ,并支持类型派生、键约束和命名空间导入/包含。<br /> 代码示例:XSD验证带命名空间的XML<br /> 以下是一个完整的XSD示例,验证上述混合文档:<br /> <!-- schema.xsd --><br /> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/mixed" xmlns:m="http://example.com/mixed" xmlns:doc="http://doc.org" xmlns:math="http://w3.org/math" elementFormDefault="qualified"></p> <p> <xs:import namespace="http://doc.org" schemaLocation="doc.xsd"/><br /> <xs:import namespace="http://w3.org/math" schemaLocation="math.xsd"/></p> <p> <xs:element name="mixed" type="m:mixedType"/><br /> <xs:complexType name="mixedType"><br /> <xs:sequence><br /> <xs:element ref="doc:title"/><br /> <xs:element name="content"><br /> <xs:complexType><br /> <xs:choice minOccurs="0" maxOccurs="unbounded"><br /> <xs:element ref="doc:para"/><br /> <xs:element ref="doc:list"/><br /> <xs:element ref="math:math"/> <!-- 明确允许math:math --><br /> </xs:choice><br /> </xs:complexType><br /> </xs:element><br /> </xs:sequence><br /> </xs:complexType><br /> </xs:schema></p> <p><!-- doc.xsd (子模式) --><br /> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://doc.org" xmlns:doc="http://doc.org"><br /> <xs:element name="title" type="xs:string"/><br /> <xs:element name="para" type="xs:string"/><br /> <xs:element name="list"><br /> <xs:complexType><br /> <xs:sequence><br /> <xs:element name="item" type="xs:string" maxOccurs="unbounded"/><br /> </xs:sequence><br /> </xs:complexType><br /> </xs:element><br /> </xs:schema></p> <p><!-- math.xsd (子模式) --><br /> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://w3.org/math" xmlns:math="http://w3.org/math"><br /> <xs:element name="math"><br /> <xs:complexType><br /> <xs:sequence><br /> <xs:any namespace="http://www.w3.org/1998/Math/MathML" processContents="lax"/><br /> </xs:sequence><br /> </xs:complexType><br /> </xs:element><br /> </xs:schema><br /> 要验证XML:<br /> <!-- valid.xml --><br /> <m:mixed xmlns:m="http://example.com/mixed" xmlns:doc="http://doc.org" xmlns:math="http://w3.org/math"><br /> <doc:title>Document Title</doc:title><br /> <content><br /> <doc:para>Some text.</doc:para><br /> <math:math><mi>x</mi></math:math><br /> </content><br /> </m:mixed><br /> 使用Xerces或libxml2等工具验证:<br /> # 使用xmllint (libxml2) 验证<br /> xmllint –schema schema.xsd valid.xml –noout<br /> 如果XML有效,输出”valid.xml validates”。XSD明确处理命名空间,避免了DTD的歧义。<br /> XSD的其他优势<br /> 类型系统<br /> :支持复杂类型和简单类型,允许命名空间特定的约束。<br /> 可扩展性<br /> :通过<br /> <xs:include><br /> 和<br /> <xs:import><br /> 轻松集成多命名空间。<br /> 工具支持<br /> :现代IDE(如Eclipse、Visual Studio)提供XSD编辑和验证插件。<br /> 结论:从DTD向现代标准的演进<br /> DTD在XML命名空间中的局限性——缺乏URI支持、前缀不兼容、内容模型歧义和实体问题——源于其设计时代未预见的复杂性。这些局限性带来了互操作性、维护性、安全性和性能挑战,尤其在多命名空间环境中。例如,在金融XML(如FpML)或医疗数据交换中,这些问题可能导致严重错误。<br /> 然而,通过转向XML Schema,这些挑战可被有效解决。XSD的命名空间感知设计提供了精确的验证机制,确保数据的完整性和可靠性。作为最佳实践,建议在新项目中优先使用XSD,并逐步迁移遗留DTD系统。如果您正在处理XML验证问题,考虑使用工具如Saxon或Oxygen XML Editor来自动化转换。<br /> 如果您有特定XML场景需要进一步分析,请提供更多细节,我可以生成定制化的指导文章。</p> </div> <div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="margin-top:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--50)"> <div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained"> <div style="height:var(--wp--preset--spacing--40)" aria-hidden="true" class="wp-block-spacer"> </div> <hr class="wp-block-separator has-text-color has-contrast-3-color has-alpha-channel-opacity has-contrast-3-background-color has-background is-style-wide" style="margin-bottom:var(--wp--preset--spacing--40)"/> <nav class="wp-block-group is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-2b923ac6 wp-block-group-is-layout-flex" style="padding-top:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40)" aria-label="Posts"> <div class="post-navigation-link-previous wp-block-post-navigation-link"><span class="wp-block-post-navigation-link__arrow-previous is-arrow-arrow" aria-hidden="true">←</span><a href="https://ziliao.tiaomu.com/113129201/" rel="prev"><span class="post-navigation-link__label">Previous: </span> <span class="post-navigation-link__title">揭秘Highcharts金融图表库:轻松绘制精准数据图表,助力金融决策精准导航</span></a></div> <div class="post-navigation-link-next wp-block-post-navigation-link"><a href="https://ziliao.tiaomu.com/113129203/" rel="next"><span class="post-navigation-link__label">Next: </span> <span class="post-navigation-link__title">揭秘WSDL点击取货:电商物流新趋势,如何提升购物体验?</span></a><span class="wp-block-post-navigation-link__arrow-next is-arrow-arrow" aria-hidden="true">→</span></div> </nav> </div> </div> </main> <footer class="wp-block-template-part"> <div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="padding-top:var(--wp--preset--spacing--50);padding-bottom:var(--wp--preset--spacing--50)"> <div class="wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-3a88641f wp-block-columns-is-layout-flex"> <div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:30%"> <div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-831b2db5 wp-block-group-is-layout-flex"> <p class="wp-block-site-title has-medium-font-size"><a href="https://ziliao.tiaomu.com" target="_self" rel="home">资料库 – 中文知识库</a></p> </div> </div> <div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:20%"> </div> <div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%"> <div class="wp-block-group is-content-justification-space-between is-layout-flex wp-container-core-group-is-layout-cf54d0a6 wp-block-group-is-layout-flex"> <div class="wp-block-group is-vertical is-content-justification-stretch is-layout-flex wp-container-core-group-is-layout-d8dce8eb wp-block-group-is-layout-flex"> <h2 class="wp-block-heading has-medium-font-size has-body-font-family" style="font-style:normal;font-weight:600">About</h2> <div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-bce0c455 wp-block-group-is-layout-flex"> <nav style="font-style:normal;font-weight:400" class="has-small-font-size is-vertical wp-block-navigation is-layout-flex wp-container-core-navigation-is-layout-bce0c455 wp-block-navigation-is-layout-flex" aria-label="About"><ul style="font-style:normal;font-weight:400" class="wp-block-navigation__container has-small-font-size is-vertical wp-block-navigation" aria-label="About"><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Team</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">History</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Careers</span></a></li></ul></nav> </div> </div> <div class="wp-block-group is-vertical is-content-justification-stretch is-layout-flex wp-container-core-group-is-layout-d8dce8eb wp-block-group-is-layout-flex"> <h2 class="wp-block-heading has-medium-font-size has-body-font-family" style="font-style:normal;font-weight:600">Privacy</h2> <div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-bce0c455 wp-block-group-is-layout-flex"> <nav style="font-style:normal;font-weight:400" class="has-small-font-size is-vertical wp-block-navigation is-layout-flex wp-container-core-navigation-is-layout-bce0c455 wp-block-navigation-is-layout-flex" aria-label="Privacy"><ul style="font-style:normal;font-weight:400" class="wp-block-navigation__container has-small-font-size is-vertical wp-block-navigation" aria-label="Privacy"><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Privacy Policy</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Terms and Conditions</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Contact Us</span></a></li></ul></nav> </div> </div> <div class="wp-block-group is-vertical is-content-justification-stretch is-layout-flex wp-container-core-group-is-layout-d8dce8eb wp-block-group-is-layout-flex"> <h2 class="wp-block-heading has-medium-font-size has-body-font-family" style="font-style:normal;font-weight:600">Social</h2> <div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-bce0c455 wp-block-group-is-layout-flex"> <nav style="font-style:normal;font-weight:400" class="has-small-font-size is-vertical wp-block-navigation is-layout-flex wp-container-core-navigation-is-layout-bce0c455 wp-block-navigation-is-layout-flex" aria-label="Social Media"><ul style="font-style:normal;font-weight:400" class="wp-block-navigation__container has-small-font-size is-vertical wp-block-navigation" aria-label="Social Media"><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Facebook</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Instagram</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Twitter/X</span></a></li></ul></nav> </div> </div> </div> </div> </div> <div class="wp-block-group alignwide is-layout-flow wp-block-group-is-layout-flow" style="padding-top:var(--wp--preset--spacing--50);padding-bottom:0"> <p class="has-contrast-2-color has-text-color has-link-color has-small-font-size wp-elements-1 wp-block-paragraph"> Designed with <a href="https://wordpress.org" rel="nofollow">WordPress</a> </p> </div> </div> </footer> </div> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/twentytwentyfour/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script data-wp-router-options="{"loadOnClientNavigation":true}" fetchpriority="low" id="@wordpress/block-library/navigation/view-js-module" src="https://ziliao.tiaomu.com/wp-includes/js/dist/script-modules/block-library/navigation/view.min.js?ver=1bf28ded04f9f188bdcb" type="module"></script> <script id="wp-emoji-settings" type="application/json"> {"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://ziliao.tiaomu.com/wp-includes/js/wp-emoji-release.min.js?ver=7.1.3"}} </script> <script type="module"> /*! This file is auto-generated */ var e="script#wp-emoji-settings",t=document.querySelector(e);if(!(t instanceof HTMLScriptElement))throw new Error("Element missing: "+e);const r=JSON.parse(t.text),s=(window._wpemojiSettings=r,"wpEmojiSettingsSupports"),o=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(s,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const r=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===r[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,r){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!r(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,r){let a;const s=(a="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),o=(s.textBaseline="top",s.font="600 32px Arial",{});return e.forEach(e=>{o[e]=t(s,e,n,r)}),o}function a(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}r.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(s));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(o),u.toString(),c.toString(),p.toString()].join(",")+"));",r=new Blob([e],{type:"text/javascript"});const a=new Worker(URL.createObjectURL(r),{name:"wpTestEmojiSupports"});return void(a.onmessage=e=>{i(n=e.data),a.terminate(),t(n)})}catch(e){}i(n=f(o,u,c,p))}t(n)}).then(e=>{for(const n in e)r.supports[n]=e[n],r.supports.everything=r.supports.everything&&r.supports[n],"flag"!==n&&(r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&r.supports[n]);var t;r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&!r.supports.flag,r.supports.everything||((t=r.source||{}).concatemoji?a(t.concatemoji):t.wpemoji&&t.twemoji&&(a(t.twemoji),a(t.wpemoji)))}); //# sourceURL=https://ziliao.tiaomu.com/wp-includes/js/wp-emoji-loader.min.js </script> <noscript><link rel="stylesheet" href="https://ziliao.tiaomu.com/wp-content/themes/abiz/assets/css/all.min.css?ver=6.5.1"></noscript> </body> </html>