Este artículo proviene de un motor de traducción automática.

Windows PowerShell

Cree interfaces para XML fáciles de usar con Windows PowerShell

Joe Leibowitz

Descargar el ejemplo de código

El lenguaje de scripting de Windows PowerShell hace todo lo que desee una herramienta de línea de comandos para realizar — y mucho más — que eventualmente podrían sustituir tecnologías como VBScript.Para una buena descripción general de lo que trata de Windows PowerShell y los conceptos básicos de usarlo, consulte bit.ly/LE4SU6 y bit.ly/eBucBI.

Windows PowerShell está completamente integrado con el Microsoft .net Framework y así está profundamente conectada a XML, el estándar internacional actual para intercambio de datos con archivos de texto estructurados.Para obtener información general sobre XML, consulte bit.ly/JHfzw.

Este artículo explora la capacidad de Windows PowerShell para presentar y manipular datos XML con el objetivo de crear una interfaz de usuario relativamente simple para leer y editar archivos XML.La idea es hacerlo más fácil y más cómodo usando algoritmos que "comprenden" las relaciones de hermanos y padres e hijos de cualquier archivo, incluso sin conocimiento previo del esquema.También te examino el uso de formularios Windows Forms en Windows PowerShell, consulta de XPath y otras tecnologías relacionadas.La aplicación propuesta puede digerir un archivo XML y emitir consultas XPath en su propio.

Veamos cómo puede analizar cualquier archivo XML en Windows PowerShell y presentarlo en un formato que pueden utilizar personas sin conocimientos técnicos avanzados.Figura 1 muestra una vista previa del tipo de GUI puede crear.

Preliminary View of the GUIFigura 1 Vista preliminar de la GUI

La clave para hacer que esto suceda es permitir la aplicación de energía-Shell de Windows analizar y entender cualquier archivo XML sin orientación humana o conocimiento previo de su esquema.Después de investigar las tecnologías existentes para el análisis automatizado de archivos XML, decidí desarrollar un motor de análisis para este propósito específico, porque lo que he podido encontrar no abordar plenamente la necesidad de entender los documentos XML sin visión humana.En la actualidad, las aplicaciones universalmente parecen asumir que un desarrollador o usuario se familiarizó con los elementos, atributos y esquema general de cualquier documento XML dado.Pero algunos — posiblemente muchos — situaciones en el mundo real no entran en este paradigma.Por ejemplo, en un escenario con muchos consumidores de datos que no son expertos XML, pero que necesitan tener acceso a una variedad de orígenes de datos XML, falla el supuesto conocimiento del paradigma existente.Del mismo modo, incluso con un experto capacitado o dos en personal, si una organización se enfrenta a cientos o miles de archivos XML estructurados de manera diferente, manipulación humana fácilmente podría verse sobrecargado.

Por lo tanto, lo que se necesita es un motor de análisis que leer cualquier archivo XML y emiten XPaths que los usuarios normales, con sólo un mínimo de entrenamiento, se pueden utilizar para buscar y editar cualquier archivo XML.

El motor de análisis de XML

Para ser compatible con XML, deben coincidir con soportes de apertura y cierre de un documento.Por ejemplo, si un elemento <ABC> existe, debe también existir en algún momento posterior en el mismo archivo de un elemento </ABC>.Entre estos de apertura y corchetes de cierre, teóricamente casi cualquier cosa puede ocurrir.Utilizando este principio fundamental de XML, te voy a mostrar cómo construir automáticamente una serie de consultas XPath que incluso relativamente inexpertos consumidores de datos XML pueden ponerlos rápidamente para encontrar y manipular los datos en archivos XML.

En primer lugar, establecer un conjunto de matrices para sostener todo abriendo y cerrando los soportes en el archivo XML:

[int[]]$leading_brackets = @()
[int[]]$closing_brackets = @()
[string[]]$leading_value = @()
[string[]]$closing_value = @()

Para construir una matriz inflexible de tamaño desconocido en Windows PowerShell, son necesarios tres elementos: el [tipo [[]] líder parte; una parte del nombre de $; y el símbolo de una matriz de tamaño desconocido, @ (). Variables en Windows PowerShell toman $ como su protagonista. Estas matrices particulares cubren las ubicaciones indizadas de apertura y cierre de corchetes en el documento XML, así como los valores de cadena de los nombres de elemento asociados con estos soportes. Por ejemplo, en el archivo XML línea valor de texto <PS1> </PS1>, el índice entero de los soportes principales sería 0, y el índice de los soportes de cierre sería 15. El líder y los valores de cierre en este caso sería PS1.

Para conseguir nuestro objetivo XML en la memoria, utilizamos el siguiente código:

 

$xdoc = New-Object System.Xml.XmlDocument
       $xdoc.Load("C:\temp\XMLSample.xml")

Figura 2 es una vista parcial del archivo XML real que se utiliza.

Figura 2 vista parcial del archivo XML de muestra

<?xml version="1.0" encoding="utf-8"?>
<Sciences>
  <Chemistry>
    <Organic ID="C1" origination="Ancient Greece" age="2800 yrs">
      <branch ID="C1a">
        <size>300</size>
        <price>1000</price>
        <degree>easy&gt;</degree>
        <origin>Athens</origin>
        // Text for organic chem here
      </branch>
      <branch name="early" ID="C1b" source="Egypt" number="14">
        <size>100</size>
        <price>3000</price>
        <degree>hard&gt;</degree>
        <origin>Alexandria</origin>
        // Text for original Egyptian science
      </branch>
    </Organic>
  </Chemistry>
<Physics></Physics>
<Biology ID="B" origination="17th century" >
.
.
.
<Trees4a name="trees4a" age="40000000">
        <type ID="Tda1">oakda</type>
        <type ID="Tda2">elmda</type>
        <type ID="Tda3">oakd3a</type>
      </Trees4a>
    </Plants>
  </Biology>
</Sciences>

Después de la operación de carga, estos datos XML están en la memoria. Con el fin de manipular y analizar XML, usar el modelo de objetos de documento que ahora se crea una instancia de la variable de $xdoc (pero también necesitaré utilizar la tecnología de XPathNavigator para unos fines especiales, como se señala más adelante en este artículo):

# Create an XPath navigator (comments in PowerShell code take the \"#\" leading character)
$nav = $xdoc.CreateNavigator()

Una de las características más interesantes de Windows PowerShell es la función integrada o cmdlet, llamado a Get-Member, que le permite examinar los métodos y propiedades de cualquier objeto en el derecho de Windows PowerShell en el IDE de desarrollo. Figura 3 incluye una llamada a este cmdlet en el objeto de nav $ sólo creado, y figura 4 muestra los resultados mostrados en el Windows PowerShell Integrated Scripting entorno (ISE) cuando se realiza la llamada Get-Help.

Figura 3 resultados de llamada Get-Member

Get-Member -InputObject $nav
                      TypeName: System.Xml.DocumentXPathNavigator
Name                 MemberType Definition
----                 ---------- ----------
AppendChild          Method     System.Xml.XmlWriter AppendChild(), System.V...
AppendChildElement   Method     System.Void AppendChildElement(string prefix...
CheckValidity        Method     bool CheckValidity(System.Xml.Schema.XmlSche...
Clone                Method     System.Xml.XPath.XPathNavigator Clone()
ComparePosition      Method     System.Xml.XmlNodeOrder ComparePosition(Syst...
Compile              Method     System.Xml.XPath.XPathExpression Compile(str...
CreateAttribute      Method     System.Void CreateAttribute(string prefix, s...
CreateAttributes     Method     System.Xml.XmlWriter CreateAttributes()
CreateNavigator      Method     System.Xml.XPath.XPathNavigator CreateNaviga...
DeleteRange          Method     System.Void DeleteRange(System.Xml.XPath.XPa...
DeleteSelf           Method     System.Void DeleteSelf()
Equals               Method     bool Equals(System.Object obj)
Evaluate             Method     System.Object Evaluate(string xpath), System...
GetAttribute         Method     string GetAttribute(string localName, string...
GetHashCode          Method     int GetHashCode()
TypeName: System.Xml.DocumentXPathNavigator
.
.
.
.
.
Value                Property   System.String Value {get;}
ValueAsBoolean       Property   System.Boolean ValueAsBoolean {get;}
ValueAsDateTime      Property   System.DateTime ValueAsDateTime {get;}
ValueAsDouble        Property   System.Double ValueAsDouble {get;}
ValueAsInt           Property   System.Int32 ValueAsInt {get;}
ValueAsLong          Property   System.Int64 ValueAsLong {get;}
ValueType            Property   System.Type ValueType {get;}
XmlLang              Property   System.String XmlLang {get;}
XmlType              Property   System.Xml.Schema.XmlSchemaType XmlType {get;}

Results of Get-Help in Windows PowerShell
Figura 4 resultados de Get-Help en Windows PowerShell

Mientras Get-Member a menudo te pondrá en el camino correcto durante el desarrollo de Windows PowerShell, también encontrará el cmdlet Get-Help asociado handy durante este proceso.

Si escribe xml get-help en la línea de comandos, como se muestra en la figura 4, obtendrá el resultado que se muestra a continuación:

getName                 Category  Synopsis
----                 --------  --------
Export-Clixml        Cmdlet    Creates an XML-based representation of an object or...
Import-Clixml        Cmdlet    Imports a CLIXML file and creates corresponding obj...
ConvertTo-XML        Cmdlet    Creates an XML-based representation of an object.     
Select-XML           Cmdlet    Finds text in an XML string or document.             
about_format.ps1xml  HelpFile  The Format.ps1xml files in Windows PowerShell defin...
about_types.ps1xml   HelpFile  Explains how the Types.ps1xml files let you extend ...

Si escribe get-help about_types.ps1xml, verá los resultados mostrados en figura 5.

Figura 5 Cómo obtener ayuda con los archivos de Types.ps1xml

TOPIC
    about_Types.ps1xml
SHORT DESCRIPTION
    Explains how the Types.ps1xml files let you extend the Microsoft .NET Framework types of the objects that are used in Windows PowerShell.
LONG DESCRIPTION
    The Types.ps1xml file in the Windows PowerShell installation directory ($pshome) is an XML-based text file that lets you add properties and methods to the objects that are used in Windows PowerShell.
Windows PowerShell has a built-in Types.ps1xml file that adds several elements to the .NET Framework types, but you can create additional Types.ps1xml files to further extend the types.
SEE ALSO
    about_Signing
    Copy-Item
    Get-Member
    Update-TypeData

El sistema integrado de Windows PowerShell para investigar la sintaxis es amplio y relativamente fácil de usar. Este es un tema digno de su propio artículo.

Para obtener el XML en condición de análisis-listo, utilice el método Select de la clase XpathNavigator:

$nav.Select("/") | % { $ouxml = $_.OuterXml }

En la primera parte de esta declaración, invoco.Seleccione la consulta XPath simples «/», dando todo el contenido XML. En la segunda parte, después del símbolo de Windows PowerShell | para su tramitación de objeto, hacer un foreach, representado por el % de alias; Podría haber usado foreach en lugar de hacerlo con el alias. Dentro del bucle, construir el trabajo XML string datos variable $ouxml de la.OuterXML propiedad de los objetos que se está tramitando en el bucle. Referencia a figura 3,.OuterXML es una de las propiedades del objeto XPathNavigator. Esta propiedad proporciona un conjunto completo de todos los soportes de ángulo en el archivo XML, que es necesario para el motor de análisis para que funcione correctamente.

Tenga en cuenta que los objetos van a través de una tubería, $_ es el símbolo de la instancia particular, con la notación de puntos utilizada para obtener las propiedades y métodos de cada instancia. Cada objeto en el gasoducto es dirigida o referenciados usando el símbolo de $_.  Para obtener un atributo del objeto $_, utilice, por ejemplo, $_.Nombre (si el nombre es una propiedad de miembro del objeto particular). Todo pasa por una tubería de Windows PowerShell es un objeto con propiedades y métodos.

Una última etapa de preparación antes de analizar para "regularizar" el texto XML por tratamiento especiales casos que parecen <ShortNode/>. El motor de análisis preferiría ver la misma información en un formato diferente: <ShortNode> </ShortNode>. El siguiente código inicia esta transformación usando RegEx y buscando coincidencias:

$ms = $ouxml | select-string -pattern "<([a-zA-Z0-9]*)\b[^>]*/>"   -allmatches
foreach($m in $ms.Matches){ ‘regularize’ to the longer format }

Ahora puede mirar el código analítico principal de esta aplicación: el motor de análisis que llenarán las cuatro matrices enumeradas anteriormente. Figura 6 muestra el código que comprueba el archivo para la apertura de los soportes.

Figura 6 probar un archivo para la apertura de los soportes

# if you run out of “<” you’re done, so use the “$found_bracket” Boolean variable to test for presence of “<”
$found_bracket = $true
while($found_bracket -eq $true)
{
  # Special case of first, or root element, of the XML document;
  # here the script-level variable $ctr equals zero.
if($Script:ctr -eq 0)
    {
    #to handle the top-level root
    $leading_brackets += $ouxml.IndexOf("<",$leading_brackets[$Script:ctr])
    $leading_value += $ouxml.Substring(0,$ind)
    $closing_brackets += $ouxml.IndexOf("</" + $leading_value[0].Substring(1))
    $Script:ctr+=1
    }
}

El código en figura 6 maneja el caso especial del elemento raíz del documento XML. Otra regla fundamental de XML es que cada esquema debe contener un único conjunto de raíz global de soportes en ángulo; dentro de estos que encierra los símbolos, los datos XML pueden estructurarse de manera consistente con la regla de coincidencia mencionada anteriormente, es decir, para cada "<ABC>" allí un "< / ABC."

Observe que la sintaxis += se utiliza para agregar un elemento o un elemento en una matriz. Más tarde, después de que se rellena con elementos, dicha matriz se accede a través de la indexación, como en $leading_brackets [3].

En los argumentos de IndexOf, observe que la posición de partida para la búsqueda, representada por el segundo parámetro del método, muestra una referencia a $Script: ctr. En Windows PowerShell, variables tienen distintos ámbitos que siguen desde donde crearon. Porque se crea la variable $ctr aquí fuera del alcance de cualquier función, se ha considerado a nivel de secuencia de comandos y una variable de nivel de secuencia de comandos no pueden cambiarse dentro de una función sin referirse a $Script. Dentro de un bucle, en lugar de dentro de una función, no podrá exigirse la referencia de Script $, pero es un buen hábito tener alcance en mente en todo momento.

Al codificar, una buena pista de una violación de alcance es una variable que debe estar cambiando en valor pero no lo es; Normalmente, esto es porque está fuera de alcance y debe ser precedido por consiguiente.

Una vez que se maneja el elemento raíz, todos los demás elementos se manejan dentro de un bloque else:

else
{
# Check for more \"<\"
$check = $ouxml.IndexOf("<",$leading_brackets[$Script:ctr-1]+1)
if($check -eq - 1)
{
break
}

La primera cosa a hacer es comprobar si se ha alcanzado el final del archivo; el criterio para ese evento es la ausencia de nuevas < símbolos. El código anterior para ello. Si no hay más < símbolos, que se llama un descanso.

El siguiente segmento de código distingue entre < casos y < casos:

#eliminate "</" cases of "<"
if($ouxml.IndexOf("</",$leading_brackets[$Script:ctr-1]+1) -ne `
  $ouxml.IndexOf("<",$leading_brackets[$Script:ctr-1]+1))

Porque está intentando acumular todos los soportes de ángulo de apertura, quieres saber solo sobre ellos en esta etapa de las operaciones del motor de análisis. Observe la sintaxis de Windows PowerShell para "igual" en las comparaciones: -ne. Relacionados con los operadores incluyen - eq,-lt y - gt. También, al igual que en Visual Basic (pero a diferencia de C#), necesita un personaje de la envoltura de la línea, el símbolo back-tick ('), para continuar una línea de código.

Si la prueba tiene éxito, rellenar la matriz de leading_brackets $ con un nuevo elemento:

$leading_brackets += $ouxml.IndexOf("<",$leading_brackets[$Script:ctr-1]+1)

Con la iteración más reciente del líderes escuadras establecido, la siguiente tarea consiste en aislar el nombre del elemento asociado. Para esta tarea, nota que después de la apertura inicial < y el nombre de elemento, < ElementName, hay un espacio seguido de uno o más atributos o cierre los soportes, como en los dos casos siguientes:

<ElementName attribute1="X" attribute2 = "Y">, or
<ElementName>

Aparte de estos dos casos con el siguiente código, que mira para ver que es lo primero, un espacio o la > símbolo:

$indx_space = $ouxml.IndexOf(" ",$leading_brackets[$Script:ctr])
  $indx_close = $ouxml.IndexOf(">",$leading_brackets[$Script:ctr])
  if($indx_space -lt $indx_close)
  {
  $indx_to_use = $indx_space
  }
  else
  {
  $indx_to_use = $indx_close
  }

Una vez que establecer el punto final adecuado, emplear $indx_to_use para ayudar a aislar la cadena asociada con la escuadra principal que ahora está en foco:

$leading_value += $ouxml.Substring($leading_brackets[$Script:ctr],($indx_to_use -
  $leading_brackets[$Script:ctr]))

En efecto, el valor de interlineado es la cadena que comienza con < y terminando ya sea con un espacio o un >.

El escenario para recoger el correlato cierre corchetes angulares por encontrar la cadena < / ElementName:

$closing_brackets += $ouxml.IndexOf("</" + $leading_value[$Script:ctr].Substring(1),`
  $leading_brackets[$Script:ctr]+1)
$Script:ctr+=1

Por último, en caso la distinción entre < y < es no cumplen, incrementar el elemento de la matriz y continuar:

else
{
$leading_brackets[$Script:ctr-1] +=1
}

Al final de este proceso, las tres matrices parecen a la siguiente presentación parcial de sus datos:

$leading_brackets:
0 18 62 109 179 207 241 360 375 447 475 509 625 639 681 713 741 775 808 844 900 915 948 976 1012 1044 1077 1142 1154 1203 1292 1329 1344 1426 1475 1490 1616 1687 1701 1743 1810 1842 1890 1904 1941 1979 2031 2046 2085 2138 2153 2186 2235 2250 2315 2362 2378 2442 2476 2524 2539 2607 2643 2718
$leading_value:
<Sciences <Chemistry <Organic <branch <size <price <degree <origin <branch <size <price <degree <origin <Physics <Biology
$closing_brackets:
2718 1687 625 360 179 207 241 273 612 447 475 509 541 1142 900 713 741 775 808 844 882 1129 948 976 1012 1044 1077 1

Establecer relaciones nodales

Ahora es el momento para la segunda fase de las operaciones del motor de análisis. En esta fase más compleja, las secuencias de $leading_brackets y $closing_brackets establecen las relaciones padre-hijo y hermano entre todos los nodos del XML que se está analizando. En primer lugar, se establece una serie de variables:

# These variables will be used to build an automatic list of XPath queries
$xpaths = @()
$xpaths_sorted = @()
$xpath = @()
[string]$xpath2 = $null

A continuación, se fija una primera sincronización de adyacentes y los soportes de cierre:

$first_open = $leading_brackets[0]
$first_closed = $closing_brackets[0]
$second_open = $leading_brackets[1]
$second_closed = $closing_brackets[1]

Y se crean algunos contadores de bucle:

$loop_ctr = 1
$loop_ctr3 = 0

El motor será analizar iterativamente no más veces que el valor de la variable de ctr $ incrementado durante la primera fase cuando construcción $leading_brackets y otros arreglos (la siguiente si la declaración es la prueba de fuego en términos de establecimiento de la estructura nodal del XML):

if($second_closed -lt $first_closed)

Si el valor de $second_closed es menos (-lt) se establece el valor de $first_closed, una relación de niño:

<ElementOneName>text for this element
  <ChildElementName>this one closes up before its parent does</ChildElementName>
</ElementOneName>

Con un nodo secundario detectado, las variables se restablecen a los siguientes dos pares adyacentes de soportes de ángulo de apertura-cierre, los contadores se incrementan y la matriz de xpath $ vital se rellena con un nuevo elemento:

$first_open = $leading_brackets[$loop_ctr]
$first_closed = $closing_brackets[$loop_ctr]
$second_open = $leading_brackets[$loop_ctr + 1]
$second_closed = $closing_brackets[$loop_ctr + 1]
$loop_ctr2 +=1
#if($loop_ctr2 -gt $depth){$loop_ctr2 -= 1}
$depth_trial+=1
$xpath += '/' + $leading_value[$loop_ctr-1]
$loop_ctr+=1

Ahora has alcanzado la etapa de procesamiento crítico para el motor de análisis: Qué hacer cuando ya no se sostiene la relación padre-hijo.

Es una cuestión preliminar eliminar duplicados que surgirán en el transcurso de las operaciones del motor de análisis. Para ello, la variable que contiene toda la matriz de consultas XPath (que es el valor de clave construido por el motor de análisis) es revisado elemento por elemento para asegurar que ya no contiene el nuevo candidato propuesto para su inclusión en $xpaths, que en este punto es el valor actual de $xpath, establecido en la octava línea del código en figura 7.

Figura 7 Comprobación de duplicados Xpaths

$is_dupe = $false
  foreach($xp in $xpaths)
  {
  $depth = $xpath.Length
  $xp = $xp.Replace('/////','')
  $xpath2 = $xpath
  $xpath2 = $xpath2.Replace(" ","")
  $xpath2 = $xpath2.Replace("<","")
  if($xp -eq $xpath2)
  {
  $is_dupe = $true
  #write-host 'DUPE!!!'
  break
}

Si el valor actual de xpath $ no es un duplicado, se anexa a la matriz de xpaths $ y $xpath se recrea como una matriz vacía para su próximo uso:

if($is_dupe -eq $false){$xpaths += ($xpath2 + '/////');}
$xpath = @()
$xpath2 = $null

El dispositivo esencial que usa el motor de análisis para continuar a través de XML iterativamente es reconstruir las matrices en cada itera-ción. Para lograr esto, el primer paso es crear nuevos objetos de matriz provisional como dispositivos de transición:

$replacement_array_values = @()
$replacement_array_opens = @()
$replacement_array_closes = @()
$finished = $false
$item_ct = 0

Los bucles de motor a través de la matriz de leading_value $ y filtra sólo el uno actual:

foreach($item in $leading_value)
{
if($item -eq $leading_value[$loop_ctr - 1] -and $finished -eq $false)
{
$finished = $true
$item_ct+=1
continue  #because this one should be filtered out
}

Sin filtrar valores están poblados en la matriz provisional. Todas las tres matrices se llenan a través de la Asociación porque la matriz de valores de nombre del elemento correspondiente en su indexación con las matrices de corchete angular de apertura y cierre:

$replacement_array_values += $item
$replacement_array_opens += $leading_brackets[$item_ct]
$replacement_array_closes += $closing_brackets[$item_ct]
$item_ct +=1

Cuando terminan las tres matrices provisionales, las tres matrices permanentes se asignan sus nuevos valores:

$leading_value = $replacement_array_values
  $opening_brackets = $replacement_array_opens
  $closing_brackets = $replacement_array_closes
  $loop_ctr+=1

La siguiente iteración de la primera fase del motor de análisis es preparada por inicializar los primeros pares adyacentes de soportes en ángulo:

$first_open = $leading_brackets[0]
$first_closed = $closing_brackets[0] 
$second_open = $leading_brackets[1] 
$second_closed = $closing_brackets[1] 
$loop_ctr = 1
$loop_ctr2 = 1
continue  # Sends the engine back to the top of the loop

Finalmente, para completar el conjunto de consultas XPath, generar rutas cortas que no podría haber incluido el proceso anteriormente descrito.Por ejemplo, en el ejemplo actual, sin este paso último extra, el \Sciences\Chemistry de XPath no sería incluido.La lógica subyacente es probar que cada versión corta de cada consulta XPath también existe, sin duplicados.La función que realiza este paso es AddMissingShortPaths, que se puede ver en la descarga de código de este artículo (archive.msdn.microsoft.com/mag201208PowerShell).

Con todas las consultas XPath automáticas en mano, listo construir una aplicación de formularios Windows Forms para usuarios.Entretanto, las consultas XPath producidas sólo se colocan en el archivo C:\PowerShell\XPATHS.txt mediante el Windows PowerShell >> Sintaxis de salida.

Construcción de la aplicación de Windows Forms

Porque Windows PowerShell alberga .net bibliotecas y clases, puede escribir el código siguiente y así poner a disposición de su aplicación de Windows Forms y las clases de dibujo de .net:

[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

Con estos elementos básicos en su lugar, puede crear un formulario y sus controles, como sigue:

$form= New-Object Windows.Forms.Form
$form.Height = 1000
$form.Width = 1500
$drawinfo = 'System.Drawing'
$button_get_data = New-Object Windows.Forms.button
$button_get_data.Enabled = $false
$text_box = New-Object Windows.Forms.Textbox
$button_get_data.Text = "get data"
$button_get_data.add_Click({ShowDataFromXMLXPathFilter})

Es de notar que add_Click es la sintaxis de Windows PowerShell para asociar un evento a un control — en este caso, colocar una llamada de función al evento click del botón. El código en figura 8 añade botones y cuadros de texto.

Figura 8 agregar botones y cuadros de texto

$pointA = New-Object System.Drawing.Point 
$listbox = New-Object Windows.Forms.Listbox 
$form.Controls.Add($listbox)
$listbox.add_SelectedIndexChanged({PopulateTextBox})
$form.Controls.Add($button_get_data)
$form.Controls.Add($text_box)
$pointA.X = 800 
$pointA.Y = 100 
$button_get_data.Location = $pointA
$button_get_data.Width = 100
$button_get_data.Height = 50
$pointA.X = 400 
$pointA.Y = 50 
$text_box.Location = $pointA
$text_box.Width = 800

Con el fin de rellenar $listbox con su colección de consultas XPath, haga lo siguiente:

foreach($item in $xpaths)
{
$listbox.Items.Add($item.Substring(0,$item.Length - 5))
# Each row in the listbox should be separated by a blank row
$listbox.Items.Add('     ')
}

La interfaz de usuario

Figura 9 muestra la interfaz de usuario con las consultas XPath generadas por la herramienta que se muestra a la izquierda, uno de los cuales fue seleccionado por el usuario.

Selecting an XPath Query
Figura 9 seleccionar una consulta XPath

En el paso final, el usuario presiona el botón de GetXMLData y produce los resultados mostrados en figura 10.

The Results Window
Figura 10 la ventana de resultados

Ahí lo tienen: una sencilla interfaz de usuario para leer y editar archivos XML, creados enteramente con Windows PowerShell. En próximos artículos en línea de MSDN Magazine, a seguir sobre este tema, enseñándole a manejar archivos XML que utilizan los espacios de nombres, así como demuestran el uso de las técnicas mostradas aquí para permitir la edición de archivos XML a través de la interfaz.

Joe Leibowitz es un consultor especializado en proyectos de infraestructura. Él puede ser contactado en joe.leibowitz@bridgewaresolutions.com.

Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Thomas Petchel