XML简易教程
2008-09-10 11:46
在Intel的早期,Andy Grove遇到一个雇员 - 他
建议公司在芯片的基础上开发个人计算机。Andy
Grove疑问道“个人计算机能做什么呢?”,这个
雇员举例说,它可以存储处方。Grove考虑到整个
研究、开发和市场费用要数百万美圆,最终决定
以为红绿灯提供芯片作为开始。
每个人都是事后诸葛亮。Andy Grove,不管你怎样看他,被普遍
认为是一个非常聪明的人 - 能够做出发展公司的重大决定。但
是在七十年代,不可能强求他预见到个人计算机的潜力。如果
他当时见过Excel、Quark、Photoshop、Oracle或者网络,他就会
理解把强大的处理器放在桌面上会允许软件做任何事。
但是如果没亲眼见过,谁能想到呢。在用打字机、加法机和铅
笔作为计算的工具的时代,你能解释PC和它的用途吗?
这个例子可以用在解释扩展标记语言(XML - eXtensible Markup
Language)上。现在还没有和它相似的东西,所以很难做出比
较。你可能听说过XML是HTML的替代物或XML与HTML相似,可以
定义自己的标记符。这两种说法都不全对,就象说PC是存储处
方的机器一样。
我妈妈是一个训练有素的厨师,如果我用她的配方,我的家庭
会省下很大一笔钱。
我以简单的开始。因此我打开文本编辑器,开始写一些HTML
代码:
<HTML>
<H1 ALIGN=CENTER>Recipe</H1>
<FONT FACE size=2>Chocolate Chip Bars</FONT>
在写完上面几行后,我想接着写我妈妈 的精妙菜谱。那么怎么
做呢?一份老式的Web页面。接下来呢?把我的页面的URL送给
对这个菜谱感兴趣的人们,然后让他们剥掉其中的<P>和<FONT
FACE size=2>吗?这得花些时间,我想得到实际的内容。
看看下面可能的XML标记:
<author>Carol Schmidt</author>
<recipe_name>Chocolate Chip Bars</recipe_name>
在XML中,标记符可以最好地描述内容。以这种方式,我可以肯
定任何查找出现在<recipe_name>标记符中的“Chocolate Chip”
的人都可以得到妈妈_的菜谱。进一步说,如果我的信息被象这
样的标记符(有意义的标记符)包围 - 我可以告诉其它程序如
何使用它们。我还可以通过编码把<recipe_name>标记符中的内
容放入数据库的某个域中,然后把它输出到一本书的硬拷贝中。
还有,我可以用一个支持XML的字处理器使网页的出版轻而易举。
这就是XML的本质:使标记对人和机器都可读。但是在实现这个
目标之前,应该理解用XML编码所涉及的东西。
文档要组织良好
一个XML文件必须满足两点:组织良好和有效。我们以一个组
织良好的文档开始。
我发明了一些描述菜谱的标记符,并把它们组织成一种合理
和可读的方式。它可能不是最好的标记,但是在下面的例子
中工作得很好。
<?xml version="1.0"?>
<list>
<recipe>
<author>Carol Schmidt</author>
<recipe_name>Chocolate Chip Bars</recipe_name>
<meal>Dinner
<course>Dessert</course>
</meal>
<ingredients>
<item>2/3 C butter</item>
<item>2 C brown sugar</item>
<item>1 tsp vanilla</item>
<item>1 3/4 C unsifted all-purpose flour</item>
<item>1 1/2 tsp baking powder</item>
<item>1/2 tsp salt</item>
<item>3 eggs</item>
<item>1/2 C chopped nuts</item>
<item>2 cups (12-oz pkg.) semi-sweet choc. chips</item>
</ingredients>
<directions>
Preheat oven to 350 degrees. Melt butter;
combine with brown sugar and vanilla in large mixing bowl.
Set aside to cool. Combine flour, baking powder, and salt;
set aside.Add eggs to cooled sugar mixture; beat well.
Stir in reserved dryingredients, nuts, and chips.
Spread in greased 13-by-9-inch pan.
Bake for 25 to 30 minutes until goldenbrown;
cool. Cut into squares.
</directions>
</recipe>
</list>
这就是一份可以接受的XML文档 - 告诉你XML是什么:把数据
以一种有实际意义的方式进行组织。
虽然这些标记符看起来有点象HTML,但是有很大的区别:文件
中没有指出数据如何表示的信息。版面指令,当我们准备好时,
就会从其它地方出现。这和把地址簿的信息放在数据库的字段
和记录中而不是放在字处理器产生的清单中的道理一样。数据
库可以让你把地址簿中的信息合成到标签、信封、信件或其它
任何想要的载体上面。最后,就是把这份菜谱文件合成到一种
表现语言中,如HTML或CSS。
前面说过,XML文档必须组织良好。这意味着文件必须满足以下
三项基本规则:
文档以XML定义<?xml version="1.0"?>开始。
有一个包含所有其它内容的根元素,如上面例子中的<list>
和</list>标记符。
所有元素必须合理地嵌套,不允许交叉嵌套。
上面的例子中,几个<item>元素被合理地嵌套<ingredients>和
</ingredients>标记符中。但是下面的标记却有严重的问题:
<ingredients><item></ingredients>chocolate chips</item>
于是"chocolate chips"没有被包含在ingredients清单中。因此
这份文档就没有组织好。这在HTML中可能不算什么,因为浏览器
已经被设计成可以处理这种问题。
但是在XML中却是致命的 - 应用程序将拒绝处理没有组织好的
文件。
我们现在知道组织良好非常重要,但是还不止这些
文档格式的排错
我妈妈_的清单中有数十条菜谱,甚至数百条。如果产生一个致
命错误,排错将非常困难 - 你将一行一行地寻找丢失的标记
符。如果使用几层嵌套,发现错误将很困难。
但是可以找到很好的帮助。分析器 - XML代码和报告格式错误
的应用程序可以在网上免费得到。其中最好的是Lark,它的作
者是由Tim Bray - XML规范的技术编辑和极力鼓吹者,地球上最
聪明的人之一。
我用Lark分析下面的代码。注意"chocolate chips"和它的关闭
标记符出现在</ingredients> 标记符中的位置有错误:
<?xml version="1.0"?>
<list>
<recipe>
<author>Carol Schmidt</author>
<recipe_name>Chocolate Chip Bars</recipe_name>
<meal>Dinner
<course>Dessert</course>
</meal>
<ingredients>
<item>2/3 C butter</item>
<item>2 C brown sugar</item>
<item>1 tsp vanilla</item>
<item>1 3/4 C unsifted all-purpose flour</item>
<item>1 1/2 tsp baking powder</item>
<item>1/2 tsp salt</item>
<item>3 eggs</item>
<item>1/2 C chopped nuts</item>
<item>
</ingredients>2 cups (12-oz pkg.) semi-sweet choc.
chips</item>
<directions>
Preheat overn to 350 degrees. Melt butter;
combine with brown sugar and vanilla in large mixing bowl.
Set aside to cool. Combine flour, baking powder, and salt; set aside.
Add eggs to cooled sugar mixture; beat well. Stir in reserved dry
ingredients, nuts, and chips.
Spread in greased 13-by-9-inch pan. Bake for 25 to 30 minutes
until golden brown; cool. Cut into squares.
</directions>
</recipe>
</list>
下面是分析器返回的结果:
Error Report
Line 17, column 22: Encountered </ingredients> expected </item>
... assumed </item>
Line 18, column 36: Encountered </item> with no start-tag.
有了这种信息,找到错误将不会成为问题。那么XML文件的有效性
是指什么呢?
实现有效性
最终我们将在组织良好的XML文档中加入信息。实际上,我们
有很多事要做 - 仍然有危机潜伏 - 虽然XML文件组织良好,
但还可能丢失关键信息。看看下面的例子:
<recipe>
<author>Carol Schmidt</author>
<recipe_name>Chocolate Chip Bars</recipe_name>
<meal>Dinner <course>Dessert</course> </meal>
<ingredients> </ingredients>
<directions>Melt butter; combine with, etc. ... </directions>
</recipe>
这份菜谱中没有包含ingredient,而且因为它组织良好,所以
Lark分析器也不会发现问题。管理过哪怕是最和善的数据库的
人都知道我们人类常犯的错误:如果有机会,我们会丢掉关键
信息并加入无用的废话。这就是为什么XML的发明者引入DTD -
文档类型定义(Document Type Definition)。DTD提供了一种保
证XML或多或少是你所想的方法。
让我们看看用在菜谱上的一个DTD。
<!DOCTYPE list [
<!ELEMENT recipe (recipe_name, author, meal, ingredients, directions)>
<!ELEMENT ingredients (item+)>
<!ELEMENT meal (#PCDATA, course?)>
<!ELEMENT item (#PCDATA, sub_item*)>
<!ELEMENT recipe_name (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT course (#PCDATA)>
<!ELEMENT item (#PCDATA)>
<!ELEMENT subitem (#PCDATA)>
<!ELEMENT directions (#PCDATA)>
]>
这些代码起初看起来不够友好,但当把它分解时却能看出其中
的意义。让我们详细解释之:
<!DOCTYPE list [
这行是说,包含在方括号中的是具有根元素<list>的某个文档的
DTD。如我们以前提到的,根元素包含所有其它元素。
<!ELEMENT recipe (recipe_name, meal, ingredients, directions)>
这行定义了<recipe>标记符。圆括号是说其中的四种标记符必
须按照顺序出现在<recipe>标记符中。
<!ELEMENT meal (#PCDATA, course?)>
这行需要详细的解释。我定义了以下的结构:
<meal>Here the meal name is mandatory
<course>One course name may appear, but it is not
mandatory</course>
</meal>
我这样做是因为,按照我的想法,午餐不一定特定某道菜,但
是晚餐可能要指出开胃食品、主菜和餐后甜点。通过指定
#PCDATA - 表示经过分析的字符数据(即非二进制数据)来
实现这个功能。这里,#PCDATA是文本 - 例如,“dinner”。
"course"后面的问号表示0或1对<course>标记符将出现在<meal>
标记符内。
现在让我们看看下一行:
<!ELEMENT ingredients (item+)>
这里的加号表示至少有一对<item>标记符应出现在<ingredients>
标记符内。
我们感兴趣的最后一行是:
<!ELEMENT item (#PCDATA, sub_item*)>
我把sub_item*作为一项安全措施。除了要求每个item的文本之
外,我希望计算每个item的内容的数量。星号是说在<item>标记
符中可以有子条目的数目。我不需要Chocolate Chip Bars菜谱的
任何子条目,但是当它的组成成分很复杂时就用得着。
现在让我们把这些放在一起看看我们能得到什么。
DTD的完整例子
下面是一个完整的例子。我把另一个菜谱加入文件内,并为
DTD做了注释。可以注意到我在第二个菜谱中用到子条目。
<?xml version="1.0"?>
<!--This starts the DTD. The first four lines address document structure-->
<!DOCTYPE list ][
<!ELEMENT recipe (recipe_name, author, meal, ingredients,directions)>
<!ELEMENT ingredients (item+)>
<!ELEMENT meal (#PCDATA, course?)>
<!ELEMENT item (#PCDATA, sub_item*)>
<!--These are the remaining elements of the recipe tag -->
<!ELEMENT recipe_name (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT directions (#PCDATA)>
<!--The remaining element of the meal tag -->
<!ELEMENT course (#PCDATA)>
<!--The remaining element of the item tag -->
<!ELEMENT sub_item (#PCDATA)>
]>
 
<?xml version="1.0"?>
<list>
<recipe>
<author>Carol Schmidt</author>
<recipe_name>Chocolate Chip Bars</recipe_name>
<meal>Dinner
<course>Dessert</course>
</meal>
<ingredients>
<item>2/3 C butter</item>
<item>2 C brown sugar</item>
<item>1 tsp vanilla</item>
<item>1 3/4 C unsifted all-purpose flour</item>
<item>1 1/2 tsp baking powder</item>
<item>1/2 tsp salt</item>
<item>3 eggs</item>
<item>1/2 C chopped nuts</item>
<item>2 cups (12-oz pkg.) semi-sweetchoc. chips</item>
</ingredients>
<directions>
Preheat oven to 350 degrees. Melt butter;
combinewith brown sugar and vanilla in large mixing bowl.
Set aside to cool. Combine flour, baking powder, andsalt;
set aside.Add eggs to cooled sugar mixture; beat well.
Stir in reserved dry ingredients, nuts, and chips.
Spread in greased 13-by-9-inch pan.
Bake for 25 to 30minutes until golden brown; cool.
Cut into squares.
</directions>
</recipe>
<recipe>
<recipe_name>Pasta with tomato Sauce</recipe_name>
<meal>Dinner
<course>Entree</course>
</meal>
<ingredients>
<item>1 lb spaghetti</item>
<item>1 16-oz can diced tomatoes</item>
<item>4 cloves garlic</item>
<item>1 diced onion</item>
<item>Italian seasoning
<sub_item>oregano</sub_item>
<sub_item>basil</sub_item>
<sub_item>crushed red pepper</sub_item>
</item>
</ingredients>
<directions>
Boil pasta. Sauté garlic and onion.
Add tomatoes.Serve hot.
</directions>
</recipe>
</list>
既然有DTD,文档将被检查看是否符合DTD做出的限制。换句话
说,我们要保证文档的有效性。
为了达到这个目的,我们需要另一个工具:有效性分析器。微软
的MSXML,一个基于Java的程序,使用容易又工作得很好。上面的
文档经过这个程序的检查后没有发现错误。但是如果我检查一个
ingredient标记符中没有包含条目的菜谱,将会返回以下信息:
ingredients is not complete. Expected elements [item].
XML的未来
现在你已经知道XML。确实,结构有点复杂,而且DTD有各种可
以定义文档可以包含的内容的选项。但还不只这些。
考虑一个数据交换对其很重要的产业,如银行。银行使用所有
权系统来跟踪内部的交易,但是如果他们在Web上使用一种通用
的XML格式,那么他们必须描述交易信息给另一个机构或应用程
序(如Quicken或MS Money)。当然,他们也可以在Web页面上
表示数据。FYI:这个标记不存在。它叫做OFEX,开放金融交易
格式(Open Financial Exchange)。
在某种情况下,如果PC上的IE 4碰到一个<SOFTPKG> 标记符,一
个函数会被启动以给用户更新已安装的软件的机会。如果你用
的是Windows 98,你可能看见过这种情况,但是不知道它是一
个XML应用程序。
这里我们有三个XML应用程序,看起来与Andy Grove在70年代看
到的加法机、打字机和铅笔不同。但是与最终出现在PC上的应
用程序相似,XML的好处可以被一般性地描述为:“当你使用人
类和机器可读的标记符描述你的数据时,会有好事发生的。”
这些好事是什么呢?我不知道。但是我也不知道我的PC上的下
一代程序将会是什么样。只要数据以这种方式标记,可以产生
不同的应用。
你开始考虑它会扩展到什么程度了吗?
我们有很多XML的实际应用可以谈论,我会在不久的将来谈到它
们的。既然我们都是网民,以后将是XSL(扩展样式语言 -
eXtensible Style Language)了。
顺便提一句,这个菜谱确实是我妈妈_的,而且很杰出。如果你
用之,再加半杯碎椰子。

我写这篇文章是因为我真诚地关心你对我的看法。我担心的是:如果你读过我写的XML简介然后准备开始写自己的XML文档。于是你开始寻找一个已经建立的DTD来表示你的信息。你找到一个,如下所示:
<!ATTLIST fn
%attr.lang;
value CDATA #FIXED "TEXT">
<!ENTITY % attr.img "
img.type CDATA #REQUIRED
img.data ENTITY #REQUIRED">

马上你就会认为Jay一定是一个白痴。他没有说关于ATTLIST和ENTITY的任何事 - 不管它们是什么。
那么让我们谈谈这件事,先有一点耐心。
上面这些行可能不好看,但实际上没什么。它们被用在DTD中来定义XML文档中的属性和实体。了解HTML的人会对这很清楚。属性是带有HTML标记符的条目,用来更准确地描述标记符。在经常出现的<img src="my.gif" height="20" width="20">中,有两个属性:height和width。你在后面会看到,在XML文档使用属性与之很相似。
对实体也没有什么新东西。如果你用过&,你就已经掌握了最基本的东西。一个被&和分号包围起来的字符串用来表示另一个或一套字符。(这里有ISO实体的完整清单。)
当然,XML中属性和实体还有其它功能。这就不可避免地要引入语法,虽然不太多。一旦知道了这些,就会不费劲地使用XML文档。
简化菜谱
如果你读过我写的XML简介,你会记得用简单的标记符表示的菜谱中的组成成分,如<item>2 cups flour</item>。在写完那篇文章后,我在网上漫游,发现关于菜谱的另一个XML文档。其中的菜谱元素如下所示:

<ingredient quantity="2" units="cups">flour</ingredient>
这种方法有一个实际的好处:可以更容易控制数据。用第一种方法,<item>标记符用来容纳一堆不同的信息。如果我想提取组成成分的清单而不需要各成分的量,我就不会那么做。
我可以用如下的结构取得相似的功能:

<item>flour
<quantity>2</quantity>
<units>cups</units>

这可以被处理,但是有两个问题:首先,item元素包含了混合的内容:文本和其它标记符。我很快就发现应该尽量避免这种结构。其次是标记符几乎没有独立的意义。很难想象只要units而不要实际的组成成分的情况。这些条目可以被简单描述,我宁愿把它们当作属性。
首先要注意的是属性名,quantity和units只有被能够翻译它们的应用程序处理时才有意义。
在被包含在有效的文档中之前,应告诉DTD来允许它。对于上面的ingredient元素,我们在DTD中只包含了以下代码:
<!ELEMENT ingredient #PCDATA>
<!ATTLIST ingredient quantity CDATA #REQUIRED>
<!ATTLIST ingredient units CDATA #REQUIRED>

第一行看起来很熟悉 - 在任何DTD中都能看到的标准元素定义。每个ATTLIST行都依次包含以下信息:

<!ATTLIST ingredient quantity CDATA #REQUIRED>
这是属性依附的元素。
<!ATTLIST ingredient quantity CDATA #REQUIRED>
这里定义属性名。
<!ATTLIST ingredient quantity CDATA #REQUIRED>
这里设置属性类型。CDATA代表字符数据。意味着处理器在属性内可以得到文本。
<!ATTLIST ingredient quantity CDATA #REQUIRED>
最后的部分定义属性的缺省值。可以使用实际的数值,如3。这样,XML中空白长度的属性值将为3。输入的值将覆盖缺省值。
在上面的例子中我没有设置特定的数量,而是使用XML的关键字#REQUIRED。它告诉处理器次属性必须包含一个值。如果空白,文档将不被处理。
缺省值有另外两个关键字。第一个是#FIXED - 如果属性值在整个文档中保持相同的值。假设我定义一个p_w_picpath的标记符属性,所有图像的大小都相同,比如说100*50像素,就可以在DTD中这样定义属性:

<!ATTLIST picture length CDATA #FIXED "100 px">
<!ATTLIST picture width CDATA #FIXED "50 px">
另一个关键字是#IMPLIED,表示属性可以包含值或是空的。
下面让我们看看属性类型。
如果你决定自己写DTD,可能需要一本解释ATTLIST语句中所有组合的XML的书。但是如果借用DTD,或许只知道CDATA和另外三种属性就性了。
第一个是ID。它要求属性的值在文档中不重复。使用过数据库的人都知道唯一标志符的必要性。DTD ATTLIST语句看起来象这样:
<!ATTLIST element_name attribute_name ID #REQUIRED>
很难想象没有#REQUIRED缺省值的ID属性类型。如果那样,任何重复的或空的ID都会迫使处理器返回一个错误。ID必须以字母或下划线开始并且不能包含任何空格。
NMTOKEN类型也使用上面的命名规则。但是允许重复。它被用做传递数据给应用程序的保障。大多数程序语言,包括Java和JavaScript,在模块名中不能有空格。大多数情况下,最好保证属性符合它们的规则。
最后是枚举类型,不需要特定的关键字。而是用"|"符号包含在括号内的值,例如:
<!ATTLIST sibling (brother | sister) #REQUIRED>
如果有有限的可能的属性值,可以用这种方式。
实体
有五种预定义的XML实体,HTML编码者应该熟悉。XML文档中的字符&、<、>、"和'被分别表示为&、@lt;、>、"和&apos;。
XML很大程度上扩展了实体的功能 - 允许在DTD中定义实体以便在文档的其余部分使用。例如,我在XML文档中需要频繁使用词组"Wired Digital",可以在DTD中这样表示:
<!ENTITY wd "Wired Digital">
这样当我使用这个词组时,可以敲入&wd;。于是可以避免拼错和重复敲入相同的信息。实体可以起到字处理器中宏的作用。
被替换的文本可以任意长,但是如果真是很长,可能要把信息存储在另一个文件中。可以通过外部实体参考来实现 - 在实体名和文件的URL中使用关键字SYSTEM:
<!ENTITY text SYSTEM " http://my.url.here">
这些特征功能强大,但有一个缺点:在一个DTD内不能被扩展。为了实现扩展功能,需要一个称为参数实体的特殊工具。它在实体定义中通过在实体名前插入"%"实现。一旦被定义,参数定义可以通过用百分号和分号包围参数名来实现。
为什么这么做?看看下面的代码:

<!ELEMENT vCard (%prop.man;, (%prop.id; | %prop.del; |
%prop.tel; | %prop.geo; | %prop.org; |
%prop.exp; | %prop.sec;)*)>

这段代码来自一个公用的XML名片草稿。当定义根元素时,作者发现更容易把信息分离到不同的参数实体中。如果看看其中的一个实体表现,我们就会知道为什么了。看看下面的prop.id实体:

<!ENTITY % prop.id "
(nickname | photo | bday)">

如果每个实体都用这么长的字符串表示,元素定义将很难阅读。
现在可以读一些DTD了。
Jay Greenspan ISO-8859-1 Entities
Named
Entity Numeric
Entity Glyph Description
&#00;-
unused
horizontaltab
linefeed
unused
space
! ! exclamationmark
" " " doublequotationmark
# # numbersign
$ $ dollarsign
% % percentsign
& & & amperstand
' ' apostrophe
( ( leftparenthesis
) ) rightparenthesis
* * asterisk
+ + plussign
, , comma
- - hyphen
. . period(fullstop)
Named
Entity Numeric
Entity Glyph Description
/ / solidus(slash)
0-
9 digits0-9
: : colon
; ; semicolon
< < < less-thansign
= = equalssign
> > > greater-thansign
? ? questionmark
@ @ commercialat
A-
Z letters A-Z
[ ][ leftsquarebracket
\ \ reversesolidus(backslash)
] ] rightsquarebracket
^ ^ caret
_ _ horizontalbar(underscore)
` ` acuteaccent
a-
z letters a-z
{ { leftcurlybrace
| | verticalbar
Named
Entity Numeric
Entity Glyph Description
} } rightcurlybrace
~ ~ tilde
-
Ÿ unused
    non-breakingspace
¡ ¡ invertedexclamation
¢ ¢ centsign
£ £ poundsterling
¤ ¤ generalcurrencysign
¥ ¥ yensign
¦ ¦ brokenverticalbar
§ § sectionsign
¨ ¨ umlaut(dieresis)
© © © copyright
ª ª feminineordinal
« « leftanglequote, guillemotleft
¬ ¬ notsign
­ ­ softhyphen
® ® registeredtrademark
¯ ¯ macronaccent
Named
Entity Numeric
Entity Glyph Description
° ° degreesign
± ± plusorminus
² ² superscripttwo
³ ³ superscriptthree
´ ´ acuteaccent
µ µ microsign
¶ ¶ paragraphsign
· · middledot
¸ ¸ cedilla
¹ ¹ superscriptone
º º masculineordinal
» » rightanglequote, guillemotright
¼ ¼ one-fourth
½ ½ one-half
¾ ¾ three-fourths
¿ ¿ invertedquestionmark
À À À uppercaseA, graveaccent
Á Á Á uppercaseA, acuteaccent
   uppercaseA, circumflexaccent
Named
Entity Numeric
Entity Glyph Description
à à à uppercaseA, tilde
Ä Ä Ä uppercaseA, dieresisorumlautmark
Å Å Å uppercaseA, ring
Æ Æ Æ uppercaseAEdipthong(ligature)
Ç Ç Ç uppercaseC, cedilla
È È È uppercaseE, graveaccent
É É É uppercaseE, acuteaccent
Ê Ê Ê uppercaseE, circumflexaccent
Ë Ë Ë uppercaseE, dieresisorumlautmark
Ì Ì Ì uppercaseI, graveaccent
Í Í Í uppercaseI, acuteaccent
Î Î Î uppercaseI, circumflexaccent
Ï Ï Ï uppercaseI, dieresisorumlautmark
Ð Ð Ð uppercaseEth, Icelandic
Ñ Ñ Ñ uppercaseN, tilde
Ò Ò Ò uppercaseO, graveaccent
Ó Ó Ó uppercaseO, acuteaccent
Ô Ô Ô uppercaseO, circumflexaccent
Õ Õ Õ uppercaseO, tilde
Named
Entity Numeric
Entity Glyph Description
Ö Ö Ö uppercaseO, dieresisorumlautmark
× × multiplysign
Ø Ø Ø uppercaseO, slash
Ù Ù Ù uppercaseU, graveaccent
Ú Ú Ú uppercaseU, acuteaccent
Û Û Û uppercaseU, circumflexaccent
Ü Ü Ü uppercaseU, dieresisorumlautmark
Ý Ý Ý uppercaseY, acuteaccent
Þ Þ Þ uppercaseTHORN, Icelandic
ß ß ß lowercasesharps, German(szligature)
à à à lowercasea, graveaccent
á á á lowercasea, acuteaccent
â â â lowercasea, circumflexaccent
ã ã ã lowercasea, tilde
ä ä ä lowercasea, dieresisorumlautmark
å å å lowercasea, ring
æ æ æ lowercaseaedipthong(ligature)
ç ç ç lowercasec, cedilla
è è è lowercasee, graveaccent
Named
Entity Numeric
Entity Glyph Description
é é é lowercasee, acuteaccent
ê ê ê lowercasee, circumflexaccent
ë ë ë lowercasee, dieresisorumlautmark
ì ì ì lowercasei, graveaccent
í í í lowercasei, acuteaccent
î î î lowercasei, circumflexaccent
ï ï ï lowercasei, dieresisorumlautmark
ð ð ð lowercaseeth, Icelandic
ñ ñ ñ lowercasen, tilde
ò ò ò lowercaseo, graveaccent
ó ó ó lowercaseo, acuteaccent
ô ô ô lowercaseo, circumflexaccent
õ õ õ lowercaseo, tilde
ö ö ö lowercaseo, dieresisorumlautmark
÷ ÷ divisionsign
ø ø ø lowercaseo, slash
ù ù ù lowercaseu, graveaccent
ú ú ú lowercaseu, acuteaccent
û û û lowercaseu, circumflexaccent
Named
Entity Numeric
Entity Glyph Description
ü ü ü lowercaseu, dieresisorumlautmark
ý ý ý lowercasey, acuteaccent
þ þ þ lowercasethorn, Icelandic
ÿ ÿ ÿ lowercasey, dieresisorumlautmark