2009-06-30 11 views
8

Básicamente soy nuevo para LINQ. He visto mucho aquí y estoy bastante confundido. He visto algunos ejemplos que me permiten escribir objetos con LINQ pero realmente no los entiendo porque están en C#, lo que supongo te permite hacer cosas diferentes con LINQ (¿no?).LINQ a XML en VB.NET

De todas formas, esto es lo que estoy tratando de hacer:

Dim productXML As XDocument = XDocument.Load(_ 
    Server.MapPath("~/App_Data/products.xml")) 

Dim products As List(Of Product) = 'some query to select all products ?' 

'set up Product properties here' 
someProduct.ProductID = 'somehow get productid from XML' 

EDITAR - sólo quiero obtener una lista de todos los productos de la doc XML y ponerlos en una lista genéricos.

+2

En realidad, mots de LINQ es similar entre C# y VB; xml es una de las pocas áreas en las que existe una diferencia, y es VB la que agrega cosas, no C# ;-p –

+0

ok ... ¿así que alguna idea de cómo ayudar con este problema? – Jason

+1

Json buscando la ayuda xml ... ¡eso es un poco gracioso! –

Respuesta

11

Marc tiene razón, VB te permite hacer muchas cosas buenas. Soy un chico C#, pero acabo de derribar una solución VB para ver cómo hacerlo por ti. Publiqué el código a continuación y le expliqué las partes clave. ¡Estaba muy impresionado con las características que VB tiene para Xml!

Veo en el ejemplo del código que ya ha logrado cargar su Xml en un XDocument. Una vez que haya hecho su XDocument.Load, puede acceder al documento Xml usando alguna sintaxis especial.

Para empezar, queremos obtener todos los productos del documento; es decir, todos los elementos del producto <. Tenemos que hacer lo siguiente:

Dim products = productsDoc...<Product> 

Esto dice que desea que todos los productos> < elementos del documento. Esto nos da una colección IEnumerable de XElements.

Una vez que hemos sacado un producto individual de la colección, queremos acceder a los valores del producto, como su nombre o precio. Para hacer eso tenemos que hacer lo siguiente:

' this gets the value of the price element within a product 
product.<Price>.Value 

Aquí hay un ejemplo completo junto con la salida esperada para que usted mire:

Module Module1 

    ' some products xml to use for this example 
    Dim productsXml = <Xml> 
          <Product> 
           <Name>Mountain Bike</Name> 
           <Price>59.99</Price> 
          </Product> 
          <Product> 
           <Name>Arsenal Football</Name> 
           <Price>9.99</Price> 
          </Product> 
          <Product> 
           <Name>Formula One Cap</Name> 
           <Price>14.99</Price> 
          </Product> 
          <Product> 
           <Name>Robin Hood Bow</Name> 
           <Price>8.99</Price> 
          </Product> 
         </Xml> 

    Sub Main() 

     ' load the xml into an XDocument 
     ' NOTE: this line isn't needed when using inline XML as per this example, 
     ' but I wanted to make this code easy to modify for reading in text files 
     Dim productsDoc = System.Xml.Linq.XDocument.Parse(productsXml.ToString()) 

     ' get all <Product> elements from the XDocument 
     Dim products = From product In productsDoc...<Product> _ 
         Select product 

     ' go through each product 
     For Each product In products 
      ' output the value of the <Name> element within product 
      Console.WriteLine("Product name is {0}", product.<Name>.Value) 
      ' output the value of the <Price> element within product 
      Console.WriteLine("Product price is {0}", product.<Price>.Value) 
     Next 

    End Sub 

End Module 

La salida del programa es:

Product name is Mountain Bike 
Product price is 59.99 
Product name is Arsenal Football 
Product price is 9.99 
Product name is Formula One Cap 
Product price is 14.99 
Product name is Robin Hood Bow 
Product price is 8.99 

Espero que esto haya sido útil. Si desea obtener más información, solo pregunte :-)

¡Es difícil escribir algo coherente antes de acostarse! :-)

+1

Tres períodos ... ¿En serio? ... –

+4

Sí, es una sintaxis extraña. Si utiliza un período, solo buscará descendientes directos del nodo desde el que está desreferenciando. Los tres períodos dice que verifique todos los nodos debajo del nodo actual. –

+0

esto funcionó muy bien, aunque todavía estaría interesado en saber cómo hacerlo utilizando objetos de tipo fuerte en lugar de anónimos – Jason

0

OK, ¿qué tal esto?

Dim productXML As XDocument = XDocument.Load(_  
    Server.MapPath("~/App_Data/products.xml"))  
' 
For Each product as Product In productXML.Document.Elements("Product") 
    'do something with each product 
Next 
+0

ese enlace es para la construcción xml? No estoy buscando construir XML ... ya lo hice. es prácticamente estático en este punto. Necesito leerlo y analizarlo en objetos y luego en una lista de genéricos. – Jason

+0

¿cómo consigo que "artículo" sea un "Producto" como es el tipo de Lista (de Producto)? – Jason

+0

obtengo este error bajo "productXML" en "Del ítem In productXML Select item": Expresión de tipo System.XML.Linq.XDocument no es consultable. Asegúrese de que no le falta una referencia de ensamblado y/o importación de espacio de nombres para el proveedor de LINQ ... pero importé System.Linq .... – Jason

2

¡El doctor Jones publicó un excelente ejemplo!

Para obtener una colección de objetos de tipo nombradas en oposición a los objetos de texto anónimos (ambos están fuertemente tipado) hacer esto:

Module Module1 

' some products xml to use for this example ' 
    Dim productsXml As XElement = _ 
    <Xml> 
     <Product> 
      <Name>Mountain Bike</Name> 
      <Price>59.99</Price> 
     </Product> 
     <Product> 
      <Name>Arsenal Football</Name> 
      <Price>9.99</Price> 
     </Product> 
     <Product> 
      <Name>Formula One Cap</Name> 
      <Price>14.99</Price> 
     </Product> 
     <Product> 
      <Name>Robin Hood Bow</Name> 
      <Price>8.99</Price> 
     </Product> 
    </Xml> 

Class Product 

    Private _name As String 
    Public Property Name() As String 
     Get 
      Return _name 
     End Get 
     Set(ByVal value As String) 
      _name = value 
     End Set 
    End Property 

    Private _price As Double 
    Public Property Price() As Double 
     Get 
      Return _price 
     End Get 
     Set(ByVal value As Double) 
      _price = value 
     End Set 
    End Property 

End Class 

Sub Main() 

    ' get an IEnumerable of Product objects ' 
    Dim products = From prod In productsXml...<Product> _ 
        Select New Product With {.Name = prod.<Name>.Value, .Price = prod.<Price>.Value} 

    ' go through each product ' 
    For Each prod In products 
     ' output the value of the <Name> element within product ' 
     Console.WriteLine("Product name is {0}", prod.Name) 
     ' output the value of the <Price> element within product ' 
     Console.WriteLine("Product price is {0}", prod.Price) 
    Next 

End Sub 

End Module 
0

Puede que sea un poco tarde a la fiesta aquí, pero no puedo creer que nadie ha ofrecido la opción XmlSerializer:

Public Class Product 
    Property Description As String 
    Property Price As Double 

    Public Shared Function FromXml(serverPath As String) As IEnumerable(Of Product) 

     Using fs = IO.File.OpenRead(serverPath) 
      Dim p As New Product 
      Return New XmlSerializer(p.GetType).Deserialize(fs) 
     End Using 

    End Function 

End Class 

luego, puede volver un IEnumerable de Producto de la función compartida:

dim listOfProducts = Product.FromXml(Server.MapPath("~/App_Data/products.xml")) 

Esto no usa LinqToXml como tal, pero deserializa el xml a un iEnumerable de producto, que puede usar Linq como de costumbre.