Dieser Artikel wurde maschinell übersetzt.

Windows PowerShell

Erstellen von benutzerfreundlichen XML-Schnittstellen mit Windows PowerShell

Joe Leibowitz

Die Windows PowerShell-Skriptsprache tut alles, was Sie wollen ein Befehlszeilentool zu tun — und noch viel mehr —, dass es schließlich Technologien wie VBScript ersetzen könnte.Eine gute allgemeine Beschreibung dessen, was Windows PowerShell über und die Grundlagen der Verwendung finden Sie in bit.ly/LE4SU6 und bit.ly/eBucBI.

Windows PowerShell ist gründlich mit dem Microsoft .net Framework integriert und so tief mit XML, dem aktuellen internationalen Standard für den Datenaustausch mit strukturierte Textdateien verbunden ist.Allgemeine Informationen zu XML finden Sie unter bit.ly/JHfzw.

Dieser Artikel untersucht die Fähigkeit von Windows PowerShell zu präsentieren und Bearbeiten von XML-Daten mit dem Ziel der Schaffung einer relativ einfachen Benutzeroberflächenautomatisierungs zum Lesen und Bearbeiten von XML-Dateien.Die Idee ist, dies einfacher und bequemer mit Algorithmen, die die Geschwister und Parent-Child-Beziehungen einer bestimmten Datei, auch ohne Vorkenntnisse des Schemas "verstehen".Ich werde auch die Verwendung von Windows Forms in Windows PowerShell, XPath-Abfragen und andere verwandte Technologien untersuchen.Die vorgeschlagene app kann eine XML-Datei zu verdauen und XPath-Abfragen auf eigene emittieren.

Lassen Sie uns betrachten, wie Sie jede XML-Datei in Windows PowerShell zu analysieren und präsentieren es in einem Format, das Menschen ohne erweiterte technische Fähigkeiten verwenden können.Abbildung 1 zeigt eine Vorschau auf den Typ des GUI können Sie erstellen.

Preliminary View of the GUI
Abbildung 1 vorläufige Ansicht über die GUI

Der Schlüssel zu machen dieses geschehen ist zum Aktivieren der Windows Power-Shell-Anwendungs zu analysieren und zu verstehen jede XML-Datei ohne menschliche Führung oder Vorkenntnisse des zugehörigen Schema.Nach der Untersuchung bestehender Technologies für die automatisierte Analyse von XML-Dateien, entschied ich mich eine parsing-Engine für diesen bestimmten Zweck zu entwickeln, weil was ich finden konnte in vollem Umfang die Notwendigkeit zu verstehen, XML-Dokumente ohne menschliche Betrachtung gerecht nicht.Derzeit scheinen Anwendungen allgemein davon ausgehen, dass ein Entwickler oder Benutzer wohlgesinnte mit den Elementen, Attributen und allgemeine Schema eines gegebenen XML-Dokuments ist.Aber einige — möglicherweise viele — Situationen in der realen Welt fallen nicht unter dieses Paradigma.In einem Szenario mit vielen Daten-Verbraucher, die nicht XML-Experten aber wer benötigen Zugriff auf eine Vielzahl von XML-Datenquellen, kann beispielsweise die Vertrautheit Annahme des bestehenden Paradigmas.In ähnlicher Weise auch mit einem ausgebildeten Experten oder zwei Mitarbeiter, wenn eine Organisation konfrontiert, Hunderte oder Tausende von unterschiedlich strukturierten XML-Dateien, menschliche Behandlung könnte leicht überwältigt.

Was wir brauchen deshalb ein parsing-Engine, die jede XML-Datei lesen und ausgeben XPaths, die gewöhnliche Benutzer, mit nur einem Minimum an Training, suchen und bearbeiten alle angegebene XML-Datei verwenden können.

Der XML-Parsing

Um kompatible XML sein, müssen ein Dokument schließenden und öffnenden Klammern übereinstimmen.Beispielsweise, wenn ein Element <ABC> vorhanden ist, muss es auch zu einem späteren Zeitpunkt in der gleichen Datei ein Element vorhanden </ABC>.Zwischen diesen öffnende und schließende spitze Klammern kann fast alles theoretisch auftreten.Mit diesem grundlegende Prinzip von XML, zeige ich Ihnen wie eine umfassende Reihe von XPath-Abfragen automatisch erstellt, so dass auch relativ unerfahrenen XML Daten Verbraucher schnell sie legte können verwenden Sie zum Suchen und Bearbeiten von Daten in XML-Dateien.

Erstens schaffen Sie eine Reihe von Arrays, halten alle öffnende und schließende Klammern in der XML-Datei:

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

Um ein stark typisiertes Array unbekannter Größe in Windows PowerShell zu bauen, sind drei Elemente erforderlich: die [Typ []] Hauptrolle; $ Namensteil; und das Symbol für ein Array von unbekannter Größe, @ (). Variablen in Windows PowerShell nehmen $ als ihre Hauptrolle. Diese speziellen Arrays decken die indizierten Orte öffnende und schließende spitze Klammern in das XML-Dokument als auch die String-Werte der zugeordneten diese Klammern Elementnamen. Beispielsweise in der XML-Zeile Wert <PS1> Text </PS1>, der Integer-Index der führenden Klammern wäre 0 und der Index der schließenden Klammern wäre 15. Führenden und Schlusswerte wäre in diesem Fall PS1.

Um unser Ziel XML in den Speicher zu erhalten, verwenden wir den folgenden Code:

 

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

Abbildung 2 ist eine Teilansicht der eigentlichen XML-Datei verwendet wird.

Abbildung 2 Teilansicht der XML-Beispieldatei

<?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>

Nach dem Ladevorgang ist diese XML-Daten im Arbeitsspeicher. Ich benutze um bearbeiten und Analysieren von XML, das Document Object Model, das nun in der Variablen $Xdoc instanziiert wird (aber ich brauche auch die XPathNavigator-Technologie für ein paar besondere Zwecke, wie später in diesem Artikel verwenden):

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

Eines der interessantesten Features von Windows PowerShell ist die integrierte Funktion oder Cmdlets, namens Get-Member, mit dem Sie die Methoden und Eigenschaften eines Objekts in Windows PowerShell direkt in der IDE zu untersuchen, wie Sie entwickeln kann. Abbildung 3 enthält einen Aufruf dieses Cmdlet auf nur $Nav-Objekts erstellt, und Abbildung 4 zeigt die Ergebnisse in die Windows PowerShell Integrated Scripting Environment (ISE) angezeigt, wenn der Get-Help-Aufruf erfolgt.

Abbildung 3 Ergebnisse von Get-Member-Aufruf

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
Abbildung 4: Ergebnisse von Get-Help in Windows PowerShell

Während Get-Member oft Sie auf dem richtigen Weg bei der Entwicklung von Windows PowerShell setzen wird, finden Sie auch das zugehörige Cmdlet Get-Help praktisch während dieses Prozesses.

Wenn Sie Hilfe Xml an der Befehlszeile eingeben, wie in Abbildung 4, wirst du die hier gezeigte Ausgabe:

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 ...

Wenn Sie get-Help Get about_types.ps1xml eingeben, sehen Sie die Ergebnisse angezeigt, Abbildung 5.

Abbildung 5 Hilfe mit ps1xml-Dateien

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

Das Windows PowerShell integriert-System für die Erforschung der Syntax ist umfassend und relativ einfach zu bedienen. Dies ist ein Thema einen eigenen Artikel verdient.

Um das XML in Analyse einsatzfähiger Zustand zu erhalten, verwenden Sie die Select-Methode des XpathNavigator:

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

Rufen Sie im ersten Teil dieser Aussage ich aus.Wählen Sie auf der einfachen XPath-Abfrage "/", geben den gesamten XML-Inhalt. Im zweiten Teil, nach dem Windows PowerShell-Symbol | für seine Pipeline Objekt kann ich einer foreach-Schleife, vertreten durch die Alias-%; Ich konnte Foreach eher als Alias verwendet habe. Innerhalb der Schleife, baue ich die Arbeiten XML-Zeichenfolge Daten Variable $Ouxml aus dem.OuterXML-Eigenschaft der Objekte in der Schleife verarbeitet werden. An Abbildung 3,.OuterXML ist eine der Eigenschaften des XPathNavigator-Objekts. Diese Eigenschaft stellt einen vollständigen Satz von allen die spitzen Klammern in der XML-Datei, die für die parsing-Engine um richtig zu arbeiten erforderlich ist.

Beachten Sie, dass bei Objekten gehen durch eine Pipeline $_ das Symbol für den speziellen Fall mit Punktnotation verwendet ist, um jede Instanz Eigenschaften und Methoden zu erhalten. Jedes Objekt in der Pipeline ist gerichtet oder mit $_ Symbol verwiesen.  Um ein Attribut des Objekts _ $ zu erhalten, verwenden Sie, z. B. $_.Name (wenn eine Elementeigenschaft des bestimmten Objekts befindet). Alles durch ein Windows PowerShell-Pipeline ist ein Objekt mit Eigenschaften und Methoden.

Eine letzte Vorbereitungsphase vor der Analyse "den XML-Text zu bereinigen" durch die Behandlung von besonderen Fällen, die aussehen wie <ShortNode/>. Die parsing-Engine würde eher die gleiche Informationen in einem anderen Format angezeigt werden: <ShortNode> </ShortNode>. Der folgende Code startet diese Transformation eine RegEx und auf der Suche nach Übereinstimmungen:

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

Sie können nun die wichtigsten analytischen Code für diese Anwendung aussehen: die parsing-Engine, die die oben aufgeführten vier Arrays aufgefüllt wird. Abbildung 6 zeigt Code die Datei für die Öffnung der Klammern zu testen.

Abbildung 6 Tests eine Datei zum Öffnen von Klammern

# 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
    }

Der Code in Abbildung 6 behandelt den Sonderfall der das Root-Element des XML-Dokuments. Eine weitere Grundregel von XML ist, dass jedes Schema insgesamt Stamm einheitlicher spitzen Klammern enthalten soll; innerhalb dieser Symbole einschließen, können die XML-Daten in irgendeiner Weise mit der übereinstimmende Regel erwähnt, das heißt, für jeden "<ABC>" gibt die strukturiert sein ein "< / ABC."

Beachten Sie, dass die +=-Syntax verwendet wird, ein Element oder ein Element eines Arrays hinzu. Nach, die mit Elementen aufgefüllt werden, kann später ein solches Array zugegriffen werden, über die Indizierung, wie in $Leading_brackets [3].

Die IndexOf-Argumente, beachten Sie, dass die Startposition für die Suche, vertreten durch den zweiten Parameter der Methode einen Verweis auf $Script zeigt: Ctr. In Windows PowerShell haben Variablen unterschiedliche Bereiche, die Folgen von wo sie geschaffen sind. Da die Variable $Ctr hier außerhalb des Bereichs der jede Funktion erstellt wird, es hat als Skript-Ebene, und eine Skript-Ebene-Variable kann nicht innerhalb einer Funktion ohne verweisen auf $Script geändert werden. In einer Schleife Mal anstatt innerhalb einer Funktion, die $Script Referenz kann nicht verlangt werden, aber es ist eine gute Angewohnheit Bereich überhaupt im Auge zu behalten.

Bei der Codierung ist ein guter Anhaltspunkt für eine Verletzung des Gültigkeitsbereich einer Variablen, die im Wert verändern werden sollte aber nicht; in der Regel ist dies, weil es außerhalb des Gültigkeitsbereichs und muss dementsprechend vorangestellt werden.

Sobald das Root-Element behandelt wird, sind alle anderen Elemente in einem else-Block behandelt:

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

Das erste, was zu tun ist zu prüfen, ob das Ende der Datei erreicht wurde; das Kriterium für dieses Ereignis ist das Fehlen von weiteren < Symbole. Der vorangehende Code tut dies. Wenn es nicht mehr gibt < Symbole, nennt man eine Pause.

Das nächste Segment Code unterscheidet zwischen < Fällen und < / Fälle:

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

Weil Sie versuchen, alle die öffnenden spitzen Klammern zu sammeln, wollen Sie nur über diese zu diesem Zeitpunkt von Analysevorgängen Motor wissen. Beachten Sie die Windows PowerShell-Syntax für "nicht gleich" im Vergleich: -Ne. Im Zusammenhang mit Operatoren gehören - Eq-Lt und - gt. Auch, wie in Visual Basic (aber im Gegensatz zu c#) benötigen Sie ein Zeilenumbruch-Zeichen, das Rücken-Tick-Symbol ('), eine Codezeile fortgesetzt.

Wenn der Test erfolgreich ist, Array $Leading_brackets durch ein neues Element zu füllen:

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

Mit der neuesten Iteration der führenden Winkelklammern gegründet besteht die nächste Aufgabe, den Namen des zugeordneten Elements zu isolieren. Beachten Sie, dass für diese Aufgabe nach der ersten Eröffnung < und Elementnamen, < ElementName, entweder ein Leerzeichen gefolgt von einem oder mehreren Attributen, oder schließen Sie die Klammern, wie in den folgenden zwei Fällen:

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

Diese beiden Fälle mit den folgenden Code, der schaut, um zu sehen, was zuerst eintritt, ein Leerzeichen getrennte oder die > Symbol:

$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
  }

Sobald Sie den richtigen Endpunkt herstellen, setzen Sie $Indx_to_use zum isolieren die Zeichenfolge zugeordnet die führende Spitze Klammer, die jetzt im Fokus:

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

Wert für der Zeilenabstand ist in der Tat die Zeichenfolge beginnend mit < und endend mit entweder ein Leerzeichen oder ein >.

Ist die Bühne zu holen, das Korrelat schließen Winkelklammern durch Suche nach die Zeichenfolge < / ElementName:

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

Schließlich, im Falle der Unterscheidung zwischen < und < / ist nicht erfüllt, das Arrayelement zu erhöhen und weiter:

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

Am Ende dieses Prozesses sehen die drei Arrays wie die folgende partielle Präsentation ihrer Daten:

$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

Nodal Beziehungen

Jetzt ist es Zeit für die zweite Phase in Analysevorgängen Motor. In dieser Phase eine komplexere schaffen die Sequenzen von $Leading_brackets und $Closing_brackets die Eltern-Kind und Geschwister Beziehungen alle Knoten des XML analysiert wurde. Zunächst werden eine Reihe von Variablen festgelegt:

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

Als nächstes wird eine erste Kopplung benachbarter führender und schließende Klammern fixiert:

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

Und einige Schleifenzähler erstellt werden:

$loop_ctr = 1
$loop_ctr3 = 0

Der Motor wird iterativ analysieren nicht mal mehr als der Wert der Variable $Ctr erhöht, während der ersten Phase arrays beim Aufbau der $Leading_brackets und anderen (folgende Wenn-Anweisung der Lackmus-Test im Hinblick auf die Einführung der nodal Struktur des XML ist):

if($second_closed -lt $first_closed)

Wenn der $Second_closed Wert ist kleiner als (-Lt) der $First_closed Wert, ein Kind-Verhältnis entsteht:

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

Mit einem Kindknoten erkannt die Variablen auf die nächsten zwei angrenzende Paare von öffnen-schließen Winkelklammern zurückgesetzt werden, werden die Zähler inkrementiert und vital $Xpath-Array wird mit einem neuen Element aufgefüllt:

$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

Sie haben jetzt die kritische Verarbeitungsstufe für die parsing-Engine erreicht: Was tun, wenn die Eltern-Kind-Beziehung nicht mehr aufnehmen.

Eine vorläufige Angelegenheit ist, Duplikate zu beseitigen, die im Zuge der Motor Analysevorgängen entstehen wird. Dazu ist die Variable, die das gesamte Array von XPath-Abfragen (die den Wert des Schlüssels erstellt, indem die parsing-Engine) überprüften Element von Element um sicherzustellen, dass es nicht bereits enthält den neuen vorgeschlagenen Kandidaten für die Aufnahme in $Xpaths, die zu diesem Zeitpunkt der aktuelle Wert von $Xpath ist, gegründet die achte Zeile des Codes in Abbildung 7.

Abbildung 7 Überprüfung auf doppelte 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
}

Wenn der aktuelle Wert von $Xpath kein Duplikat ist, es an das Array $Xpaths angehängt und $Xpath als ein leeres Array für den nächsten Einsatz wieder erstellt:

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

Das wesentliche Gerät von der parsing-Engine verwendet, um durch die XML iterativ weiter ist die Arrays bei jeder Itera-Tion wieder aufzubauen. Um dies zu erreichen, ist der erste Schritt um neue vorläufige Arrayobjekte als Übergangs-Geräte zu erstellen:

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

Der Motor durchläuft das Array $Leading_value und filtert heraus nur die aktuellen eine:

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
}

Ungefilterte Werte werden in das interim-Array gefüllt. Alle drei Arrays werden über Verein aufgefüllt, da das Array Element Name-Werte entspricht in seiner Indizierung mit dem öffnenden und dem schließenden spitzen Klammer-Arrays:

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

Wenn die drei vorläufigen Arrays abgeschlossen sind, werden die drei ständigen Arrays ihre neuen Werte zugewiesen:

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

Die nächste Iteration der ersten Phase der parsing-Engine ist bereit gemacht, durch die erste angrenzende Paare von spitzen Klammern initialisieren:

$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

Schließlich führen Sie für den Satz von XPath-Abfragen generieren Sie kurze Wege, die der oben beschriebene Prozess nicht aufgenommen haben könnte.Zum Beispiel würde im aktuellen Beispiel, ohne diesen zusätzlichen letzten Schritt, die XPath-\Sciences\Chemistry nicht aufgenommen werden.Die zugrunde liegende Logik ist zu überprüfen, ob jeder kürzerer Version von jeder XPath-Abfrage auch, ohne Duplikate existiert.Die Funktion dieser Schritt führt ist AddMissingShortPaths, die Sie im Codedownload für diesen Artikel sehen können (archive.msdn.microsoft.com/mag201208PowerShell).

Alle die automatischen XPath-Abfragen in der Hand können Sie eine Windows Forms-Anwendung für Benutzer erstellen.In der Zwischenzeit sind die XPath-Abfragen, die gerade produziert in die Datei C:\PowerShell\XPATHS.txt über die Windows-PowerShell setzen >> Ausgabe-Syntax.

Die Windows Forms-Anwendung erstellen

Da Windows PowerShell .net Bibliotheken und Klassen hostet, können schreiben Sie folgenden Code und damit für Ihre Anwendung Windows Forms und die Zeichenklassen von .net zur Verfügung stellen:

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

Mit diesen grundlegenden Bausteine vorhanden können Sie ein Formular und dessen Steuerelemente wie folgt erstellen:

$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 ist erwähnenswert, dass Add_Click ist Windows PowerShell Syntax zur Befestigung ein Ereignis eines Steuerelements — in diesem Fall einen Funktionsaufruf zum Click-Ereignis der Schaltfläche Anfügen. Der Code in Abbildung 8 fügt Schaltflächen und Textfelder.

Abbildung 8 Hinzufügen von Schaltflächen und Textfelder

$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

Um $Listbox mit Ihrer Sammlung von XPath-Abfragen zu füllen, gehen Sie folgendermaßen vor:

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

Die Benutzeroberfläche

Abbildung 9 zeigt die Benutzeroberfläche mit der XPath-Abfragen generiert durch das Tool angezeigt, auf der linken Seite, von denen einer vom Benutzer ausgewählt wurde.

Selecting an XPath Query
Abbildung 9 Auswählen einer XPath-Abfrage

Im letzten Schritt der Benutzer drückt die Schaltfläche GetXMLData und liefert die Ergebnisse angezeigt, Abbildung 10.

The Results Window
Abbildung 10 das Ergebnisfenster

Dort haben Sie es — eine einfache Benutzeroberfläche zum Lesen und Bearbeiten von XML-Dateien, die vollständig mit Windows PowerShell erstellt. Bevorstehende MSDN Magazin-online-Artikel werde ich weiter auf dieses Thema zeigt Ihnen, wie Sie XML-Dateien bearbeiten, die Namespaces verwenden, sowie veranschaulichen die Verwendung der Techniken zum Bearbeiten von XML-Dateien über die Schnittstelle hier gezeigt.

Joe Leibowitz ist ein Berater, spezialisiert auf Infrastrukturprojekte. Er kann erreicht werden unter joe.leibowitz@bridgewaresolutions.com.

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Thomas Petchel