在消息分配中使用非规范 XPath

如果使用 .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属性标记