XML格式

我曾经使用过一个颇受欢迎的 XML 命令行工具,因为我注意到它有一个选项可以把目录内容列表保存为 XML 文档。我好奇地试了试。看到的结果如清单 1 所示。


清单 1. 原来的格式
        
<xml>
<d p="rwxrwxrwx" a="2005.07.26 15:23:13" 
    m="2005.07.26 15:21:23" s="170" n="."/>
<d p="rwxrwxrwx" a="2005.07.26 15:21:30" 
    m="2005.06.10 13:49:59" s="2448" n=".."/>
<f p="rw-r--r--" a="2005.07.26 15:20:46" 
    m="2005.06.07 14:00:55" s="6148" n=".DS_Store"/>
<f p="rw-r--r--" a="2005.07.26 15:21:30" 
    m="2005.07.26 15:21:24" s="800" n="canonthunderbirdplist.xml"/>
<f p="rw-r--r--" a="2005.07.26 15:21:30" 
    m="2005.07.26 15:20:46" s="945" n="thunderbirdplist.xml"/>
</xml>

这种格式至少有三种不同的错误,虽然不是致命的但都很重要。这是设计 XML 格式一个经典的反例,但是稍加调整就能使其更容易使用,更加健壮。

用 XML 作元素名

第一个问题是根元素的名称。字符串 “xml” 被 XML 规范保留,除了万维网联盟(W3C)外,任何人都不能在任何传播的格式中使用。W3C 可能在将来的规范中重定义该名称(以及所有其他以 xml 或者任何组合方式开始的名称)。这并不是一种结构良好性错误,但是有些解析器读到该文档时仍然会发出警告。

这个名称的第二个问题是它不具有描述性。当然,它确实是 XML。如果包含 XML 声明这一点会更明显。根元素的名称应该反映文档的类型。比如对该元素来说 DirectoryListing 就是不错的选择。


缩写的名称

第二个主要的问题是对元素和属性使用缩写名。f 是什么?还有 pams 又是什么?我能猜出来,因为我知道这些数据来自哪里,但是对于别人来说就不那么清楚了。最好把全名拼出来,如清单 2 所示。


清单 2. 完整的名称
<DirectoryListing>
  <Directory permissions="rwxrwxrwx" size="170" name="."
        lastAccessed="2005.07.26 15:23:13" 
        lastModified="2005.07.26 15:21:23"/>
  <Directory permissions="rwxrwxrwx"  size="2448" name=".."
        lastAccessed="2005.07.26 15:21:30" 
        lastModified="2005.06.10 13:49:59"/>
  <File permissions="rw-r--r--" size="6148" name=".DS_Store"
        lastAccessed="2005.07.26 15:20:46" 
        lastModified="2005.06.07 14:00:55"/>
  <File permissions="rw-r--r--" size="800" name="canonthunderbirdplist.xml"
        lastAccessed="2005.07.26 15:21:30" 
        lastModified="2005.07.26 15:21:24"/>
  <File permissions="rw-r--r--"   size="945" name="thunderbirdplist.xml"
        lastAccessed="2005.07.26 15:21:30" 
        lastModified="2005.07.26 15:20:46"/>
</DirectoryListing> 

是不是这样清楚得多?虽然稍微长了点,但是不存在问题了。如果文件大小很重要(虽然很少如此),那么还有减少磁盘和内存占用而不会导致含糊不清的方法。


非 XML 结构

最后一个问题可能最严重。属性包含大量不能通过 XML 解析器访问的子结构。解析此文档的每个程序都必须包含自定义的解析器,用于解析权限格式和时间格式。为什么不让 XML 解析器来完成这些困难的工作呢?这些属性应该放到包含必要的子结构的子元素中。比如,可以这样设计 permissions 子元素:

<permissions>
  <world>
    <read>true</read>
    <write>false</write>
    <execute>false</execute>
  </world>
  <group>
    <read>true</read>
    <write>true</write>
    <execute>false</execute>
  </group>
  <owner>
    <read>true</read>
    <write>true</write>
    <execute>false</execute>
  </owner>
</permissions>

如果愿意的话也可使用属性,但是应该把权限分别放在单独的属性中:

<File size="945" name="thunderbirdplist.xml"
  lastAccessed="2005.07.26 15:21:30" lastModified="2005.07.26 15:20:46" 
  worldread="true" worldwrite="false" worldexecute="false"
  groupread="true" groupwrite="true"  groupexecute="false"
  ownerread="true" ownerwrite="true"  ownerexecute="false"
/>

至少有十几种不同的方式,但是无论哪种方法都应该通过 XML 标记使结构明确清晰,不要隐含在文本字符串中。XML 解析器的目的是为客户机应用程序提供单独的信息片段,而不是要求客户机程序再进一步分解内容。

类似地,可以对时间信息作如下分解:

<lastModified>
  <year>2005</year>
  <month>06</month>
  <day>10</day> 
  <hour>13</hour>
  <minute>49</minute>
  <second>59</second>
</lastModified>

在某种程度上,时间都是统一的,因此保留无区分的字符串可能也行。但是,字符串格式应该进一步标准化,以便很容易用模式语言验证,或者作为各种日期时间库的输入,如 java.util.Date。ISO 8601 时间格式就很好:

lastModified="2005-06-10T13:49:59"

如果将来需要,ISO 8601 还定义了表示时区和小数秒的语法。


结束语

清单 3 显示了文档的最终版本。


清单 3. 改进的格式
<?xml version="1.0" encoding="UTF-8"?>
<DirectoryListing>
  <Directory size="170" name="."
        lastAccessed="20050726T15:23:13" lastModified="20050726T15:21:23">
    <Permissions>
      <world>
        <read>true</read>
        <write>true</write>
        <execute>true</execute>
      </world>
      <group>
        <read>true</read>
        <write>true</write>
        <execute>true</execute>
      </group>
      <owner>
        <read>true</read>
        <write>true</write>
        <execute>true</execute>
      </owner>
    </Permissions>
  </Directory>
  <Directory size="2448" name=".."
        lastAccessed="20050726T15:21:30" lastModified="20050610T13:49:59">
    <Permissions>
      <world>
        <read>true</read>
        <write>true</write>
        <execute>true</execute>
      </world>
      <group>
        <read>true</read>
        <write>true</write>
        <execute>true</execute>
      </group>
      <owner>
        <read>true</read>
        <write>true</write>
        <execute>true</execute>
      </owner>
    </Permissions>
  </Directory>
  <File size="6148" name=".DS_Store"
        lastAccessed="20050726T15:20:46" lastModified="20050607T14:00:55">
    <Permissions>
      <world>
        <read>true</read>
        <write>false</write>
        <execute>false</execute>
      </world>
      <group>
        <read>true</read>
        <write>false</write>
        <execute>false</execute>
      </group>
      <owner>
        <read>true</read>
        <write>true</write>
        <execute>false</execute>
      </owner>
    </Permissions>
  </File>
  <File size="800" name="canonthunderbirdplist.xml"
        lastAccessed="20050726T15:21:30" lastModified="20050726T15:21:24">
    <Permissions>
      <world>
        <read>true</read>
        <write>false</write>
        <execute>false</execute>
      </world>
      <group>
        <read>true</read>
        <write>false</write>
        <execute>false</execute>
      </group>
      <owner>
        <read>true</read>
        <write>true</write>
        <execute>false</execute>
      </owner>
    </Permissions>
  </File>
  <File size="945" name="thunderbirdplist.xml"
        lastAccessed="20050726T15:21:30" lastModified="20050726T15:20:46">
    <Permissions>
      <world>
        <read>true</read>
        <write>false</write>
        <execute>false</execute>
      </world>
      <group>
        <read>true</read>
        <write>false</write>
        <execute>false</execute>
      </group>
      <owner>
        <read>true</read>
        <write>true</write>
        <execute>false</execute>
      </owner>
    </Permissions>
  </File>
</DirectoryListing>

虽然长了些,但是更清晰,也更便于处理。不要害怕冗长。如果需要更短、更简单的格式,可以使用 XSLT 样式表转换。但是,取出额外的结构比放入它要简单得多。

缩写名称和含糊的字符串格式是只有 32K 内存、速度数千赫兹的超级计算机时代的遗留问题。已经不属于这个时代了。设计 XML 格式的时候,应该强调清晰和准确而不是紧凑。设计应针对易理解性和可维护性,而不是榨出每个字节。要方便那些处理您的文档的每个人,也包括您自己。


如果要将一个函数或变量定义为全局的函数或者变量,则可以先考虑将其定义为静态变量,这样可以防止外部文件调用该函数和变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值