Freigeben über


Verwenden nicht-kanonischer XPaths in Nachrichtenzuweisungen

Bei der Verwendung von .NET-Nachrichtenteilen können Sie Ihren Code mit einer Anmerkung mit dem XML-Serialisierungsattribut zu versehen. Wenn außerdem Anmerkungen mit gekennzeichneten Feldern und/oder Eigenschaften vorhanden sind, können recht komplexe XPath-Ausdrücke entstehen. Solche komplexen XPath-Ausdrücke sind möglicherweise nicht-kanonisch. Ein nicht-kanonischer XPath sollte jedoch nur in direkt gebundenen Orchestrierungen verwendet werden, da er in logisch oder physikalisch gebundenen Orchestrierungen fehlschlagen könnte. Direkt gebundene Orchestrierungen verwenden für die Verarbeitung des XML-Dokuments keine Pipeline. Daher wird das gesamte XML-Dokument vor der Verarbeitung in den Arbeitsspeicher geladen.

Kanonischer und nicht-kanonischer XPath

Die kanonische oder Kurzform von XPath verwendet die abgekürzte Syntax aus der XPath-Spezifikation (http://www.w3.org/TR/xpath), um einen Speicherortpfad anzugeben. Im Folgenden sind einige der charakteristischen Merkmale von XPath-Ausdrücken aufgelistet:

  • Die child:: Achse wird standardmäßig für jeden Schritt des Ausdrucks angenommen.

  • @ ist die Abkürzung für attribute::.

  • // ist die Abkürzung für /descendant-or-self::node()/.

  • . ist die Abkürzung für self::node().

  • .. ist die Abkürzung für parent::node().

    Kanonische XPath-Ausdrücke sind einfache Ausdrücke wie /*[local-name()='element-name' and namespaceURI()='http://MyUri.org']/*[local-name()='element-name']/@*[local-name='attribute-name'].

    Als Gegensatz hierzu kann die nicht-kanonische Form von XPath angeführt werden. Dieses Formular wird auch als "allgemeine Form" oder "beliebiger XPath" bezeichnet und zeichnet sich durch Ausdrücke aus, die beliebig komplex sind und mehrere Achsen kombinieren können: //element-name//*[local-name()='element-name' and position()=2].

Beispiel

Betrachten Sie folgendes Programm:

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();
        }
    }
}

Der Typ "Zoo" enthält das Feld "Animal", bei dem es sich entweder um eine Schlange oder einen Hund ("Snake" oder "Dog") handeln kann. Die Instanz "Animal" hat das Feld "NumberOfLegs", das mit der Anmerkung "PropertyAttribute" versehen ist, die diesem Feld die Eigenschaft "BTS.RetryCount" zuweist.

Hinweis

Eine echte Anwendung würde seine eigenen Eigenschaften definieren.

Wenn es sich bei "animal of the week" (Tier der Woche) um einen Hund handelt ("dog"), sieht die serialisierte Instanz "Zoo" folgendermaßen aus:

<Zoo>
  <Dog>
    <NumberOfLegs>4</NumberOfLegs>
  </Dog>
</Zoo>

Handelt es um eine Schlange ("snake"), sieht die serialisierte Instanz "Zoo" folgendermaßen aus:

<Zoo>
  <Snake>
    <NumberOfLegs>0</NumberOfLegs>
  </Snake>
</Zoo>

In Anbetracht des XML-Schemas, das der .NET-Klasse "Zoo" entspricht, würde der XPath-Ausdruck zum Auswählen der Eigenschaft "RetryCount" sowohl den Schritt "Snake" als auch "Dog" im Pfad zur Eigenschaft zulassen:

/*[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()='']

Die XML-Pipelinekomponenten können diesen nicht-kanonischen XPath-Ausdruck nicht verarbeiten. Sie können diese Situation vermeiden, indem Sie XML-Serialisierungsattribute mit mehreren Auswahlmöglichkeiten nicht zusammen mit den XML-Pipelines verwenden. Auch bei der Verwendung der folgenden XML-Serialisierungsattribute sollten Sie umsichtig vorgehen:

  • XmlElementAttribute

  • XmlAttributeAttribute

  • XmlArrayItemAttribute