如果使用 .Net 消息部件,则可以使用 XML 序列化属性对代码进行批注,当也附带可分辨字段和/或属性注释时,可能会导致相当复杂的 XPath 表达式。 这些复杂的 XPath 表达式可能是非规范的。 非规范 XPath 只应在直接绑定的业务流程中使用,可能会在逻辑或物理绑定的业务流程中失效。 直接绑定业务流程不依赖于管道来处理 XML 文档;因此,在处理之前,整个 XML 文档将加载到内存中。
规范 XPath 与非规范 XPath
XPath 规范或短格式使用 XPath 规范(http://www.w3.org/TR/xpath)中的缩写语法来指定位置路径。 规范 XPath 表达式的一些区分属性包括:
默认情况下,假定
child::
轴是表达式的每个步骤的一部分。@
是 的attribute::
缩写。//
是 的/descendant-or-self::node()/
缩写。.
是 的self::node()
缩写。..
是 的parent::node()
缩写。规范 XPath 表达式是简单的表达式,例如
/*[local-name()='element-name' and namespaceURI()='http://MyUri.org']/*[local-name()='element-name']/@*[local-name='attribute-name']
。这可以与 XPath 的非规范形式形成鲜明对比。 此形式也称为“通用形式”或“任意 XPath”,其特点是表达式可以任意复杂,并且可以组合多个轴:
//element-name//*[local-name()='element-name' and position()=2]
。
示例:
请考虑以下程序:
using System;
using System.IO;
using System.Xml.Serialization;
using Microsoft.XLANGs.BaseTypes;
namespace ComplexNetXPath
{
public class Animal
{
[Property( typeof(BTS.RetryCount) )]
public int NumberOfLegs;
}
public class Snake : Animal
{
public Snake()
{
NumberOfLegs = 0;
}
}
public class Dog : Animal
{
public Dog()
{
NumberOfLegs = 4;
}
}
public class Zoo
{
//
// Dogs and snakes are the possible animals of
// the week.
//
[XmlElement(typeof(Snake))]
[XmlElement(typeof(Dog))]
public Animal AnimalOfTheWeek;
}
class Class1
{
static void Main(string[] args)
{
XmlSerializer ser = new XmlSerializer(typeof(Zoo));
Stream s = Console.OpenStandardOutput();
Zoo z = new Zoo();
z.AnimalOfTheWeek = new Dog();
ser.Serialize( s, z );
s.Flush();
Console.WriteLine("------------------");
z.AnimalOfTheWeek = new Snake();
ser.Serialize( s, z );
s.Flush();
}
}
}
Zoo 类型包含一个动物字段,可以是蛇或狗。 Animal 实例有一个 NumberOfLegs 字段,该字段被批注为 PropertyAttribute,将 BTS.RetryCount 属性分配给此字段。
注释
实际应用程序将定义自己的属性。
当本周的动物是狗时,Zoo 的序列化实例如下所示:
<Zoo>
<Dog>
<NumberOfLegs>4</NumberOfLegs>
</Dog>
</Zoo>
当本周的动物是蛇时,被序列化的动物园实例如下所示:
<Zoo>
<Snake>
<NumberOfLegs>0</NumberOfLegs>
</Snake>
</Zoo>
考虑到与 .Net Zoo 类等效的 Xml 架构,用于选择 RetryCount 属性的 XPath 表达式允许蛇或狗步骤出现在通往属性的路径上。
/*[local-name()='Zoo' and namespace-uri()='']/*[(local-name()='Dog' and namespace-uri()='') or (local-name()='Snake' and namespace-uri()='')]/*[local-name()='NumberOfLegs' and namespace-uri()='']
XML 管道组件无法处理此非规范 XPath 表达式。 为了避免这种情况,不应将多选 Xml 序列化属性与 XML 管道结合使用,在使用以下 XML 序列化属性时应小心:
XmlElementAttribute
XmlAttributeAttribute
XmlArrayItem属性标记