win10 xml 使用_学习10种良好的XML使用习惯

win10 xml 使用

您喜欢XML及其提供的灵活性和互操作性,但是您可以做一些事情来使与XML的交互以及用于处理XML的工具更加容易。 使用XML时要养成一些基本的良好习惯,以确保您可以最有效地利用XML文档和应用程序。

养成10个好习惯

以下是要采用的十大XML习惯:

  1. 定义您的XML和编码
  2. 使用DTD或XSD
  3. 记得验证
  4. 验证并不总是答案
  5. XML结构与属性
  6. 使用XPath查找信息
  7. 您并不总是需要解析器来提取信息
  8. 何时在DOM解析中使用SAX
  9. 何时通过SAX解析进行DOM
  10. 使用一个好的XML编辑器

定义您的XML和编码

当您快速创建XML文档时,很容易创建基本结构并避开指定XML声明和XML文档包含的数据的编码类型的常规XML文档要求。

考虑清单1中的XML文档。

清单1.减去XML声明和数据编码类型的XML文档
<phrases>
  <phrase lang="en">Hello</phrase>
  <phrase lang="it">Buongiorno</phrase>
  <phrase lang="fr">Salut!</phrase>
</phrases>

作为一个人,您可以查看该文档并将其标识为XML,但是对于计算机而言,要实现相同的目标将更加困难。 通过将XML声明添加到文件顶部,可以使过程更加明确和可识别。 这是一行,指定文档为XML,还描述了XML数据中使用的版本号和字符编码。 例如:

<?xml version="1.0" encoding="us-ascii"?>

编码规范的内容也应该准确。 XML解析器使用该编码来确保从XML文档正确加载单个字符。 例如,继续清单1中基于短语的示例,在文档中添加俄语条目会引起问题,因为当前您指定的编码不支持俄语短语hello所需的扩展字符集。

指定错误的编码可能意味着解析器会错误地处理文档。 例如,将一个多字节扩展字符读为单个字节序列可能会导致数据损坏和错误输出。

使用DTD或XSD

一旦有了XML声明,就应确保使用DTD或XSD定义XML文件的有效结构。 两种解决方案都允许XML解析器检查并确认XML文件的内容与您要建模的数据的结构相匹配。

例如,给定一个用于联系人数据库的简单XML结构,您想要定义一个结构,该结构允许指定联系人的姓名,地址和电话号码。 使用DTD意味着您可以绘制结构并确保结构内的每个触点与布局匹配。

例如,清单2显示了contacts数据库的DTD。

清单2.联系人数据库的DTD
<!ELEMENT phone (#PCDATA)>
<!ATTLIST phone type (home | work | mobile) #REQUIRED>
<!ELEMENT contact (#PCDATA | name | phone | address)*>
<!ELEMENT contacts (#PCDATA | contact)*>
<!ELEMENT country (#PCDATA)>
<!ELEMENT road (#PCDATA)>
<!ELEMENT address (#PCDATA | road | city | state | postcode | country)*>
<!ATTLIST address type (home | work) #REQUIRED>
<!ELEMENT state (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT postcode (#PCDATA)>
<!ELEMENT city (#PCDATA)>

DTD定义了描述联系人所需的元素,属性(以及这些属性的支持值)。 例如,您可以在清单2中看到phone元素具有type属性,并且还具有该地址以及该地址中的组件的属性。

使用DTD有助于确保结构有效,并且与验证过程结合使用时,可以识别任何问题。 当与具有XML功能的编辑器一起使用时,DTD还可以帮助编辑和自动完成内容。

XSD或模式执行与DTD相同的许多功能,但是可以以不同的方式使用。 例如,尽管某些XML编辑器需要DTD才能自动完成内容,但架构可以为文档的实际层次结构设计提供更大的灵活性。 您选择的工具将取决于您自己的情况。

记得验证

查看清单3,可以发现问题吗?

清单3.一个验证示例
<contacts>
  <contact>
    <name>Martin</name>
    <phone type="home">123 456 7890</phone>
    <phone type="mobile">123 456 7890</phone>
    <phone type="work">123 456 7890</phone>
    <address type="home">
      <road>Home road</road>
      <city>Home city</city>
      <state>Home state</state>
      <zipcode>12434</zipcode>
      <country>USA</country>
    </address>
  </contact>
  <contact>
    <name>Sharon</name>
    <phone type="work">234 567 8901</phone>
    <phone>234 567 8901</phone>
    <address type="home">
      <road>Other home road</road>
      <city>Other city</city>
      <state>Other state</state>
      <zipcode>39487</zipcode>
      <country>USA</country>
    </address>
    <address type="work>
      <road>Work building, work road</road>
      <city>Work city</city>
      <state>Work state</state>
      <zipcode>12347</zipcode>
      <country>USA</country>
    </address>
  </contact>
</contacts>

手工发现问题是乏味的。 但是,可以通过xmllint运行该文件,这是一个免费工具,用于验证XML文件的内容和结构,并且在清单4中针对该文件执行输出后,您可以看到输出。

清单4.通过xmllint运行清单3之后的输出
$ xmllint contacts.xml 
contacts.xml:27: parser error : Unescaped '<' not allowed in attributes values
      <road>Work building, work road</road>
      ^
contacts.xml:27: parser error : attributes construct error
      <road>Work building, work road</road>
      ^
contacts.xml:27: parser error : Couldn't find end of Start Tag address line 26
      <road>Work building, work road</road>
      ^
contacts.xml:32: parser error : Opening and ending tag mismatch: contact line 15 
                                                       and address
    </address>
              ^
contacts.xml:33: parser error : Opening and ending tag mismatch: contacts line 1 
                                                       and contact
  </contact>
            ^
contacts.xml:34: parser error : Extra content at the end of the document
</contacts>

尽管与原始问题相比,这看起来非常复杂(其中一个属性未关闭),但确实为您提供了起点。

顺便说一句,xmllint支持许多不同的命令行选项,以帮助选择诊断方法和结果。 --noout选项是最有用的选项之一,它可以防止xmllint在解析文件时回显内容。 对于短文件,这不是问题,但是对于较长文件,则可能是问题。

如果使用的是DTD,则使用--postvalid选项来告诉xmllint针对DTD验证内容,并确保该内容不仅是有效的XML,而且还与DTD的结构匹配。 如果将您在“ 使用DTD或XSD”中为联系人文件生成的DTD添加到该文件中,并且更正了属性定义错误,则会产生另一个错误,如清单5所示。

清单5. xmllint发现了另一个错误
$ xmllint --noout --postvalid contacts.xml 
contacts.xml:9: element address: validity error : Element zipcode is not declared 
                            in address list of possible children
contacts.xml:21: element address: validity error : Element zipcode is not declared 
                            in address list of possible children
contacts.xml:28: element address: validity error : Element zipcode is not declared 
                            in address list of possible children
Document contacts.xml does not validate

以这种方式使用xmllint是确认文档结构有效的一种快速,便捷的方法。 xmllint是libxml2工具箱的一部分,它与Linux,UNIX®和Mac OS X捆绑在一起,但是需要单独下载Windows®。 有关xmllint和libxml2的更多信息,请参阅相关主题

验证并不总是答案

使用xmllint和类似的工具来验证XML文件,尤其是在使用DTD的情况下,是验证XML文件内容的好方法。 但是,该解决方案确实有其局限性。 例如,XML文件的内容呢?

使用DTD或XSD,可以为属性指定显式内容。 您只能使用字符串或ID创建属性,这些字符串或ID可以是可用选项的受限列表的一部分,但是无法以相同方式控制或限制元素的内容。

例如,在联系人示例中,电话号码元素包含数字和空格。 但是,没有什么可以阻止用户向该元素添加字母字符。 这样做不会在使用xmllint进行验证的过程中引发错误,并且编辑器和其他支持XML的解决方案也无法解决或识别问题。 您的应用程序由于标识了非标准数据类型而失败,这可能是您实际了解问题的方式。

简而言之,XML验证仅确保结构正确,而不确保数据正确。

解决此问题的最简单方法是编写一个解析器,该解析器读取XML文件并实际验证数据内容。 不过,不要过分验证内容; 您只需要确保数据满足您的应用程序要求即可。

XML结构与属性

对于使用属性或元素来描述要在XML文件中表示的信息是否更好,存在意见分歧。

通常,应使用元素(即标记之间的数据)来定义文件中包含的信息。 应该使用属性来提供对所描述数据的扩展限定。

元素和属性都有局限性。 例如,属性不能在标签内重复,这是元素优于属性的经典情况。 以这种方式支持重复信息的能力使其非常实用。 相反,使用元素来限定数据的处理有时也会更加复杂。

联系人示例中的电话号码很好地说明了这些好处。 在清单6所示的示例中,使用属性来限定电话号码的类型(例如工作,家庭或移动电话)。

清单6.限定电话号码的类型
<phone type="home">123 456 7890</phone>
<phone type="mobile">123 456 7890</phone>
<phone type="work">123 456 7890</phone>

通过这种结构,很容易从整体上挑选号码(通过忽略属性),或挑选特定的电话号码类型(通过使用属性)。

将这种结构与仅使用清单7中的元素设计的结构进行比较。

清单7.仅使用元素限定电话号码
<phone>
  <type>home</type>
  <number>123 456 7890</number>
</phone>
<phone>
  <type>mobile</type>
  <number>123 456 7890</number>
</phone>
<phone>
  <type>work</type>
  <number>123 456 7890</number>
</phone>

现在很难见到树木的树木。 尽管从理论上讲,任何XML解析器或合适的XPath定义都可以提取您想要的信息,但是您获得的却很少,同时使XML文档难以阅读。

使用XPath查找信息

使用XML数据时,查找所需信息可能很复杂。 当然,您可以编写一个解析器来挑选所需的资料,但是有时候,您实际上只需要非常快速地在文件中找到一小部分信息。

例如,如果要提取联系人XML文件中所有国家/地区的列表,以便查看联系人的分布范围,则可以使用XPath来选择信息。

XPath使您可以通过使用XML文件的结构作为查询的一部分从XML文件中提取数据。 例如,您可以通过提供XML文件中元素的路径来提取特定元素的数据:

$ xpath contacts.xml '//contact/address/country'

您可以像这样剖析内容:

  • 初始双斜杠(//)指定在文档中的任意位置查找指定的元素(联系人)。
  • 下一个斜杠和元素名称指定要提取的下一个元素(地址),即在contact元素中查找'ddress元素。
  • 最后一个重复该过程,这次是选择国家。

请注意,在此示例中,您限定了地址类型以从中选择信息,因此它将选择所有地址。 您可以在清单8中看到XPath查询的结果。

清单8. XPath查询的结果
$ xpath contacts.xml '//contact/address/country' 
Found 3 nodes:
-- NODE --
<country>USA</country>-- NODE --
<country>USA</country>-- NODE --
<country>USA</country>

如果要选择更具体的数据,则可以指定元素内容或要匹配的属性内容。 例如,要仅选择手机号码,您需要指定属性类型和值。 为此,请使用一个at符号(@),该符号指定您要搜索一个属性,然后指定要匹配的值(请参见清单9)。

清单9.仅选择手机号码
$ xpath contacts.xml '//contact/phone[@type="mobile"]' 
Found 1 nodes:
-- NODE --
<phone type="mobile">123 456 7890</phone>

清单89使用命令行工具。 许多XML工具包提供了与XPath元素一起使用的本机方法,您可以使用XPath规范提取数据以直接在您的应用程序中使用,而不必使用解析器来获取信息。

您并不总是需要解析器来提取信息

尽管这似乎是违反直觉的,但是您不必总是使用使用SAX,DOM或其​​他技术(例如XPath或XQuery)的完整XML解析器从XML文件中提取所需的信息。

XML文件包含结构化格式的数据,尽管有时您需要结构化格式的信息。 通常,当您快速查找一条信息时,一种更简单的解决方案将起作用。

通常,仅使用grep或Perl或类似的方法来提取所需的数据,而无需实际将文档的结构或内容解析为XML文件,就可以逃脱。

例如,您可以使用grep选择电话号码(请参见清单10)。

清单10.使用grep选择电话号码
$ grep '<phone' contacts.xml

<phone type="home">123 456 7890</phone>
<phone type="mobile">123 456 7890</phone>
<phone type="work">123 456 7890</phone>
<phone type="work">234 567 8901</phone>
<phone>234 567 8901</phone>

您已经选择了想要的信息,而不必担心它是XML的事实,也不必担心结构本身。

当您只需要快速获得一条信息时,简化的处理技术就可以找到所需的信息,而无需传统解析解决方案带来的开销。

何时在DOM解析中使用SAX

当为文档构建解析器以提取所需的信息时,通常很难确定何时使用基于SAX的处理器以及何时使用基于DOM的处理器。

做出决定的最简单方法是既要考虑文档的复杂性,又要考虑信息的用途。 如果您转换或翻译文档,或者文档特别大,那么SAX是您的最佳选择。

SAX逐元素解析文档,并在识别元素时触发要调用的方法或函数。 如果将XML文档转换为另一种格式,例如将XML转换为HTML,则SAX是最有效的方法。 您不必将整个文档加载到内存中,只需对要识别的元素和结构做出React即可。

SAX的缺点是,您需要保存或记录结构,或者需要整体理解文档并从文档中挑选单个元素(例如,选择一个完整的联系人)。 为此,您需要构建复杂的流程来加载XML,将数据记录到结构中,然后能够将元素标识到输出目标中。

何时在SAX解析中使用DOM

DOM处理将整个文档及其结构加载到内存中,并允许您在应用程序中引用和使用XML文档的结构。 例如,在联系人示例中,您可以将整个联系人数据库读取到内存中,然后通过遍历联系人来选择所有电话号码,然后在每个联系人中遍历每个电话号码。

因为DOM保留了该结构,更重要的是理解并使用该结构,因此您可以轻松地整体或单独使用结构。 与联系人示例保持一致,使用SAX插入新联系人将很复杂。 但是,使用DOM,您只需将代表新联系人的新XML元素插入现有XML文档中即可。

DOM的局限性在于,处理流中的文件(例如转换为HTML)变得更加复杂,因为您必须通过遍历结构中的每个元素来处理文档。

此外,由于DOM在解析过程中将整个XML文档加载到内存中,因此DOM解析器可能会变慢,并且显然需要更多内存。 DOM流程提供了与此相关的一些好处; 例如,您可以从一个解析中多次处理使用DOM解析的XML文档。 使用SAX,您必须重复分析多次才能获得相同的结果。

请参阅相关主题 ,以了解更多详细信息,并使用DOM和SAX的例子。

使用一个好的XML编辑器

如果您定期编写和使用XML,那么一个好的XML编辑器是必须的。 XML编辑器与标准文本编辑器不同,因为他们了解XML的结构和布局。 它们可以提供使使用XML更容易的各种功能,包括:

  • 完成-开始为结束元素输入字符,然后他们可以为您完成其余字符的输入。
  • 内容完成-如果您将XML文件与DTD一起使用,则它们可以为您填充内容的一部分并设置其格式。 例如,在联系人DTD中,phone元素的type属性是必需元素。 使用智能XML编辑器,当您创建电话标签时,属性(带有空值)会自动引入到文本中。
  • 内联格式-编辑器可以使您的XML更易于阅读和理解。 这可以在编辑时实时完成,也可以通过单独的格式命令完成。 最终结果是XML,您可以更快地理解和识别。
  • 内置验证-键入时,编辑器可以验证XML文档是否存在错误,并在编辑器中突出显示不同的问题,以便您知道要解决的问题。
  • 内置的转换和转换-一些XML编辑器包括XPath,XQuery的接口,在某些情况下还包括XSLT和其他转换的接口,因此您可以在编辑环境中查看结果。
  • 学习和操作-有时您在DTD之前创建XML结构。 在这种情况下,可以读取XML文件,了解结构并创建DTD进行验证的编辑器可以节省大量时间和精力。

优秀的XML编辑器的示例包括Eclipse和oXygenXML,但还有许多其他选择。

摘要

学习XML的良好习惯可以在利用XML提供的功能与努力克服XML标准以获得正确的验证和解析基础之间有所不同。 本文应帮助您养成10个良好的习惯,这些习惯可以在您处理XML文档和数据时提高效率和效率。


翻译自: https://www.ibm.com/developerworks/xml/library/x-tengoodxmlhabits/index.html

win10 xml 使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值