分析属性值
大部分情况下,属性值都是一个简单的文本字符串。然而,这并不意味着实际应用中的属性值都是字符型的。有时候,属性值是由许多种类型的数据组合而成的,例如date或boolean,这时,你就要用xmlconvert或system.convevt类的方法把这些类型转换成原来的类型。xmlconvert和system.convevt类都能实现数据类型的转换,但是xmlconvert类依据xsd中指定的数据类型进行转换,而不管它现在是什么类型。
假设你有以下的xml数据片断:
让我们先确认,birthdaay属性值是february 8, 2001,如果你用system.convert类把该字符串转换成.net framework中的datetime类型,这样,我们就可以把它当成date类型使用了。相比下,如果你用xmlconvert类来转换字符串,你将看到一个分析错误,因为xmlconvert类不能正确解释这个字符串中的日期。因为在xml中,日期型数据的格式必须是yyyy-mm-dd形式的。xmlconvert类担任clr类型与xsd类型之间的相互转换工作。当转换工作发生时,转换结果是局部的。
在某些解决方案中,属性值是由纯文本和实体共同组成的。在所有的阅读器类中,只有xmlvalidatingreader类能处理实体。xmltextreader虽然不能处理实体,但它们同时出现在属性值中的时候,它只能把文本值取出来。出现这种情况,你必须用readattribute&#118alue方法替代简单的读方法来分析属性值的内容。
readattribute&#118alue方法分析属性值,然后把各个组成的要素分隔开(如把纯文本和实体分开)。你可以用readattribute&#118alue方法的返回值作为循环条件,遍历整个属性值中的要素。既然xmltextreader类不能处理实体,那么你可以自己写一个用于处理实体的类。下面的代码片断演示了怎么调用一个自定义的处理类:
while(reader.readattribute&#118alue())
{
if (reader.nodetype == xmlnodetype.entityreference)
/ resolve the "reader.name" reference and add
/ the result to a buffer
buf += yourresolvercode(reader.name);
else
/ just append the &#118alue to the buffer
buf += reader.&#118alue;
}
当属性值全部被分析后,readatribute&#118alue方法返回false, 从而结束循环。属性值的最终结果就是全局变量buffer的值了。
处理xml文本(text)
当我们在处理xml标签文本时,如果不能正确的处理,它的错误原因能很快地确定。例如一个字符转换错误,它必然是传输了非xml文本到一个xml数据流中。不是所有在给定的平台中有效的字符都是有效的xml字符。只有在xml规范(www.w3.org/tr/2000/rec-xml-20001006.html)中规定的有效的字符才能安全的用作元素和属性名。
xmlconvert类提供了把非xml标准的命名转换成标准的xml命名的功能。当标签名中包含有无效的xml字符时,encodename 和 decodename方法能把它们调整成符合schema的xml命名。包括sql server!#8482; 和microsoft office,这些应用程序允许及支持unicode文档,然而,这些文档中的字符有些也不是有效的xml命名。典型的情况是在你处理数据库中包含空格的列名时。虽然sql server允许长列名,但这对xml流来说可能就不是有效的命名。空格会被十六进制代码invoice_0x0020_details替代。下面的代码演示了怎么样在程序中获得该字符串:
xmlconvert.encodename("invoice details");
与此相反的方法是decodename。该方法把xml文本转换成其原始的格式。要注意的是它只能转换完整的十六进制代码,只有_0x0020_才被当成一个空格,而_0x20_就不是了:
xmlconvert.decodename("invoice_0x0020_details");
在xml文档中的空格即重要也不重要。说它重要,是当它出现在元素的内容中或者它在注释语句中时,它能表示实际意义。例如下面的情况:
<mynode xml:space="preserve">
<!-- any space here must be preserved -->
!#8226;!#8226;!#8226;
</mynode>
在xml中,空格不只是代表空格(空白),也代表回车、换行和缩进。
通过xmltextreader类的whitespacehandling属性你可以处理空格。这个属性接受及返回一个whitespacehandling枚举值(该枚举类有三种可选值)。默认值是all,它表示有意义和无意义的空格都会作为节点返回---- 分别为significantwhitespace和whitespace节点。 另一个枚举值是none,它表示对任何空格都不作为节点返回。最后,就是signficant枚举值,它表示忽略没有意义的空格,而只返回节点类型为signficantwhitespace的节点。注意whitespacehandling属性是少数阅读器属性中的一个。它能被改变在任何时候和给read操作带来影响。而normalization及 xmlresolver属性是“sensitive”的。