Condividi tramite


Uso di XPath non canonici nelle assegnazioni di messaggi

Se si usano parti di messaggio .Net, è possibile annotare il codice con l'attributo di serializzazione XML che, se accompagnato anche da campi distinti e/o annotazioni di proprietà, può comportare espressioni XPath piuttosto complesse. È possibile che queste espressioni XPath complesse non siano canoniche. Gli XPath non canonici devono essere usati solo nelle orchestrazioni con associazione diretta e potrebbero fallire con orchestrazioni associate logicamente o fisicamente. Le orchestrazioni associate dirette non si basano su una pipeline per l'elaborazione del documento XML; di conseguenza, l'intero documento XML viene caricato in memoria prima dell'elaborazione.

XPath canonico e non canonico

La forma canonica o breve di XPath usa la sintassi abbreviata della specifica XPath (http://www.w3.org/TR/xpath) per specificare un percorso. Alcune proprietà distintive delle espressioni XPath canoniche includono:

  • L'asse child:: viene assunto per impostazione predefinita per ogni passaggio dell'espressione

  • @ è l'abbreviazione di attribute::.

  • // è l'abbreviazione di /descendant-or-self::node()/.

  • . è l'abbreviazione di self::node().

  • .. è un'abbreviazione di parent::node().

    Le espressioni XPath canoniche sono espressioni semplici, ad /*[local-name()='element-name' and namespaceURI()='http://MyUri.org']/*[local-name()='element-name']/@*[local-name='attribute-name']esempio .

    Ciò può essere contrastato con la forma non canonica di XPath. Questo modulo è noto anche come "forma generale" o "XPath arbitrario" ed è distinto dalle espressioni che sono arbitrariamente complesse e possono combinare più assi: //element-name//*[local-name()='element-name' and position()=2].

Esempio

Si consideri il programma seguente:

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

Nel tipo Zoo è presente un campo Animale che può essere un Serpente o un Cane. L'istanza Animal ha un campo NumberOfLegs annotato con l'attributo PropertyAttribute che assegna la proprietà BTS.RetryCount a questo campo.

Annotazioni

Un'applicazione reale definirà le proprie proprietà.

Quando l'animale della settimana è un cane, l'istanza zoo serializzata è simile alla seguente:

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

Quando l'animale della settimana è un serpente, l'istanza zoo serializzata ha un aspetto simile al seguente:

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

Considerando lo schema Xml equivalente alla classe Zoo .Net, l'espressione XPath per la selezione della proprietà RetryCount consente la visualizzazione di un passaggio Snake o Dog nel percorso della proprietà :

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

I componenti della pipeline XML non possono gestire questa espressione XPath non canonica. Per evitare questa situazione, gli attributi di serializzazione Xml a scelta multipla non devono essere usati insieme alle pipeline XML e prestare attenzione quando si usano gli attributi di serializzazione xml seguenti:

  • XmlElementAttribute

  • XmlAttributeAttribute

  • XmlArrayItemAttribute