Especificar ejes en un paso de expresión de ruta de acceso
Un paso de eje en una expresión de ruta de acceso está formado por los componentes que se indican a continuación:
Para obtener más información, consulte Expresiones de ruta de acceso (XQuery).
La implementación de XQuery en SQL Server admite los pasos de eje siguientes:
Eje |
Descripción |
---|---|
child |
Devuelve elementos secundarios del nodo de contexto. |
descendant |
Devuelve todos los descendientes del nodo de contexto. |
parent |
Devuelve el elemento primario del nodo de contexto. |
attribute |
Devuelve atributos del nodo de contexto. |
self |
Devuelve el propio nodo de contexto. |
descendant-or-self |
Devuelve el nodo de contexto y todos los descendientes del mismo. |
Todos estos ejes, excepto parent, son ejes directos. El eje parent es un eje inverso, pues realiza búsquedas hacia atrás en la jerarquía del documento. Por ejemplo, la expresión de ruta de acceso relativa child::ProductDescription/child::Summary tiene dos pasos, y cada uno especifica un eje child. El primer paso recupera los elementos secundarios <ProductDescription> del nodo de contexto. Por cada nodo de elemento <ProductDescription>, el segundo paso recupera los nodos de elemento secundarios <Summary>.
La expresión de ruta de acceso relativa, child::root/child::Location/attribute::LocationID, tiene tres pasos. Cada uno de los dos primeros especifica un eje child y el tercero especifica el eje attribute. Cuando se ejecuta con los documentos XML de instrucciones de fabricación en la tabla Production.ProductModel, la expresión devuelve el atributo LocationID del nodo de elemento secundario <Location> del elemento <root>.
Ejemplos
Los ejemplos de consulta de este tema se especifican con columnas del tipo xml en la base de datos AdventureWorks2008R2. Para obtener información acerca de estas columnas, vea Representación de tipo de datos xml en la base de datos AdventureWorks2008R2.
A. Especificar un eje child
Para un modelo de producto determinado, la consulta siguiente recupera los nodos de elemento secundarios <Features> del nodo de elemento <ProductDescription> a partir de la descripción del catálogo de productos almacenada en la tabla Production.ProductModel.
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/child::PD:ProductDescription/child::PD:Features')
FROM Production.ProductModel
WHERE ProductModelID=19
Observe lo siguiente en la consulta anterior:
El método query() del tipo de datos xml especifica la expresión de ruta de acceso.
Ambos pasos de la expresión de ruta de acceso especifican un eje child y los nombres de nodo, ProductDescription y Features, como pruebas de nodo. Para obtener información acerca de las pruebas de nodo, vea Especificar una prueba de nodo en un paso de expresión de ruta de acceso.
B. Especificar ejes descendant y descendant-or-self
En el ejemplo siguiente se utilizan ejes descendant y descendant-or-self. La consulta de este ejemplo se especifica con una variable de tipo xml. Se ha simplificado la instancia XML para ilustrar claramente la diferencia en los resultados generados.
declare @x xml
set @x='
<a>
<b>text1
<c>text2
<d>text3</d>
</c>
</b>
</a>'
declare @y xml
set @y = @x.query('
/child::a/child::b
')
select @y
En el resultado siguiente, la expresión devuelve el nodo de elemento secundario <b> del nodo de elemento <a>:
<b>text1
<c>text2
<d>text3</d>
</c>
</b>
En esta expresión, si especifica un eje descendant para la expresión de ruta de acceso,
/child::a/child::b/descendant::*, está solicitando todos los descendientes del nodo de elemento <b>.
El asterisco (*) en la prueba de nodo representa el nombre del nodo como prueba de nodo. Por tanto, el tipo de nodo principal del eje descendant, el nodo de elemento, determina los tipos de nodos devueltos. Es decir, la expresión devuelve todos los nodos de elemento. No se devuelven los nodos de texto. Para obtener más información acerca del tipo de nodo principal y su relación con la prueba de nodo, vea Especificar una prueba de nodo en un paso de expresión de ruta de acceso.
Los nodos de elemento <c> y <d> se devuelven, tal como se muestra en el resultado siguiente:
<c>text2
<d>text3</d>
</c>
<d>text3</d>
Si se especifica un eje descendant-or-self en lugar de un eje descendant, /child::a/child::b/descendant-or-self::* devolverá el nodo de contexto, el elemento <b> y su descendiente.
Este es el resultado:
<b>text1
<c>text2
<d>text3</d>
</c>
</b>
<c>text2
<d>text3</d>
</c>
<d>text3</d>
La consulta de ejemplo siguiente en la base de datos AdventureWorks2008R2 recupera todos los nodos de elemento descendientes del elemento secundario <Features> del elemento <ProductDescription>:
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/child::PD:ProductDescription/child::PD:Features/descendant::*
')
FROM Production.ProductModel
WHERE ProductModelID=19
C. Especificar un eje parent
La consulta siguiente devuelve el elemento secundario <Summary> del elemento <ProductDescription> en el documento XML del catálogo de productos almacenado en la tabla Production.ProductModel.
En este ejemplo se utiliza el eje parent para volver al elemento primario del elemento <Feature> y recuperar el elemento secundario <Summary> del elemento <ProductDescription>.
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/child::PD:ProductDescription/child::PD:Features/parent::PD:ProductDescription/child::PD:Summary
')
FROM Production.ProductModel
WHERE ProductModelID=19
En este ejemplo de consulta, la expresión de ruta de acceso utiliza el eje parent. Puede volver a escribir la expresión sin el eje parent, tal como se muestra a continuación:
/child::PD:ProductDescription[child::PD:Features]/child::PD:Summary
A continuación se ofrece un ejemplo más útil del eje parent.
Cada descripción del catálogo de modelos de producto almacenada en la columna CatalogDescription de la tabla ProductModel tiene un elemento <ProductDescription> con el atributo ProductModelID y el elemento secundario <Features>, tal como se muestra en el fragmento siguiente:
<ProductDescription ProductModelID="..." >
...
<Features>
<Feature1>...</Feature1>
<Feature2>...</Feature2>
...
</ProductDescription>
La consulta establece una variable de iteración, $f, en la instrucción FLWOR para devolver el elemento secundario del elemento <Features>. Para obtener más información, vea FLWOR (instrucción e iteración de XQuery). Por cada característica, la cláusula return construye un XML de la forma siguiente:
<Feature ProductModelID="...">...</Feature>
<Feature ProductModelID="...">...</Feature>
Para agregar el ProductModelID de cada elemento <Feature>, se especifica el eje parent:
SELECT CatalogDescription.query('
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";
for $f in /child::PD:ProductDescription/child::PD:Features/child::*
return
<Feature
ProductModelID="{ ($f/parent::PD:Features/parent::PD:ProductDescription/attribute::ProductModelID)[1]}" >
{ $f }
</Feature>
')
FROM Production.ProductModel
WHERE ProductModelID=19
Éste es el resultado parcial:
<Feature ProductModelID="19">
<wm:Warranty
xmlns:wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
<wm:WarrantyPeriod>3 years</wm:WarrantyPeriod>
<wm:Description>parts and labor</wm:Description>
</wm:Warranty>
</Feature>
<Feature ProductModelID="19">
<wm:Maintenance
xmlns:wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">
<wm:NoOfYears>10 years</wm:NoOfYears>
<wm:Description>maintenance contract available through your dealer
or any Adventure Works retail store.</wm:Description>
</wm:Maintenance>
</Feature>
<Feature ProductModelID="19">
<p1:wheel
xmlns:p1="https://www.adventure-works.com/schemas/OtherFeatures">
High performance wheels.
</p1:wheel>
</Feature>
Tenga en cuenta que se agrega el predicado [1] en la expresión de ruta de acceso para garantizar que se devuelve un valor singleton.