Freigeben über


Verwenden nicht kanonischer XPaths in Nachrichtenzuweisungen

Wenn Sie .Net-Nachrichtenteile verwenden, ist es möglich, den Code mit dem XML-Serialisierungsattribut zu kommentieren, das, wenn es auch von unterschiedlichen Feldern und/oder Eigenschaftsanmerkungen begleitet wird, zu relativ komplexen XPath-Ausdrücken führen kann. Es ist möglich, dass diese komplexen XPath-Ausdrücke nicht kanonisch sind. Nicht-kanonische XPath-Elemente sollten nur bei direkt gebundenen Orchestrierungen verwendet werden, da sie bei logisch oder physisch gebundenen Orchestrierungen möglicherweise nicht korrekt funktionieren. Direkte gebundene Orchestrierungen basieren nicht auf einer Pipeline zur Verarbeitung des XML-Dokuments; Daher wird das gesamte XML-Dokument vor der Verarbeitung im Arbeitsspeicher geladen.

Normierte und nicht normierte XPath

Die kanonische oder kurze Form von XPath verwendet die abgekürzte Syntax aus der XPath-Spezifikation (http://www.w3.org/TR/xpath) zum Angeben eines Speicherortpfads. Einige unterscheidungsbezogene Eigenschaften von kanonischen XPath-Ausdrücken umfassen:

  • Die child:: Achse wird für jeden Schritt des Ausdrucks standardmäßig 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'].

    Dies kann mit der nicht kanonischen Form von XPath kontrastiert werden. Dieses Formular wird auch als "allgemeine Form" oder "beliebiger XPath" bezeichnet und unterscheidet sich von Ausdrücken, die willkürlich komplex sind und mehrere Achsen kombinieren können: //element-name//*[local-name()='element-name' and position()=2]

Beispiel

Betrachten Sie das folgende 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 Zootyp enthält ein Tierfeld, das entweder eine Schlange oder ein Hund sein kann. Die Animal-Instanz weist ein NumberOfLegs-Feld auf, das mit dem PropertyAttribute versehen ist, welches die BTS.RetryCount-Eigenschaft diesem Feld zuweist.

Hinweis

Eine echte Anwendung würde ihre eigenen Eigenschaften definieren.

Wenn das Tier der Woche ein Hund ist, sieht die serialisierte Zoo-Instanz wie folgt aus:

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

Wenn das Tier der Woche eine Schlange ist, sieht die serialisierte Zoo-Instanz wie folgt aus:

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

In Anbetracht des XML-Schemas, das der .Net Zoo-Klasse entspricht, würde der XPath-Ausdruck zum Auswählen der RetryCount-Eigenschaft entweder eine Schlange oder einen Dog-Schritt auf dem Pfad zur Eigenschaft anzeigen:

/*[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. Um diese Situation zu vermeiden, sollten Xml-Serialisierungsattribute mit mehrfacher Auswahl nicht in Verbindung mit den XML-Pipelines verwendet werden, und bei Verwendung der folgenden XML-Serialisierungsattribute sollten Sie darauf achten:

  • XmlElementAttribute

  • XmlAttributeAttribute

  • XmlArrayItemAttribute