Condividi tramite


Utilizzo di Xpath non canonici nelle assegnazioni messaggio

Se si utilizzano parti di messaggio .NET, è possibile commentare il codice con l'attributo di serializzazione XML che, se accompagnato anche da campi differenzianti e/o annotazioni di proprietà, può dar luogo a espressioni XPath alquanto complesse. È possibile che queste espressioni XPath complesse siano espressioni non canoniche. Le espressioni XPath non canoniche devono essere utilizzate solo nelle orchestrazioni con binding diretto e possono generare errori con orchestrazioni con binding logico o fisico. Le orchestrazioni con binding diretto non si avvalgono di una pipeline per l'elaborazione del documento XML, pertanto viene caricato in memoria l'intero documento prima dell'elaborazione.

Espressioni XPath canoniche e non canoniche

La forma canonica o breve di XPath usa la sintassi abbreviata dalla specifica XPath (http://www.w3.org/TR/xpath) per specificare un percorso di posizione. Di seguito sono riportate alcune delle proprietà specifiche delle espressioni XPath:

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

  • @ è breve per attribute::.

  • // è breve per /descendant-or-self::node()/.

  • . è breve per self::node().

  • .. è breve per parent::node().

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

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

Esempio

Considerare il programma riportato di seguito:

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

Il tipo Zoo contiene un campo Animal il cui valore può essere Snake o Dog. L'istanza Animal presenta un campo NumberOfLegs annotato con PropertyAttribute che assegna la proprietà BTS.RetryCount a questo campo.

Nota

Un'applicazione reale definirebbe le proprie proprietà.

Quando l'animale della settimana è un cane, l'istanza Zoo serializzata è:

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

Quando l'animale della settimana è un serpente, l'istanza Zoo serializzata è:

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

Considerando l'XML Schema equivalente alla classe .NET Zoo, l'espressione XPath per la selezione della proprietà RetryCount consentirebbe la presenza 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 prevenire questa situazione, è necessario evitare di utilizzare attributi di serializzazione XML a scelta multipla insieme alle pipeline XML e prestare attenzione quando si utilizzano gli attributi di serializzazione XML seguenti:

  • XmlElementAttribute

  • XmlAttributeAttribute

  • XmlArrayItemAttribute