XML Node per Powershell in der Mitte einfügen
Hallo,
ich habe eine XML-Datei in der ich Elemente in der Mitte hinzufügen möchte. Genauer gesagt möchte ich die erste "SW.Blocks.CompileUnit" clonen dahinter einfügen.
Die XML:
Und meine Powershell:
FehlerMeldung:
Wie kann ich die Fehlermeldung beheben bzw. den letzten Node Löschen bzw. die Newnode an einer bestimmten Position einfügen?
ich habe eine XML-Datei in der ich Elemente in der Mitte hinzufügen möchte. Genauer gesagt möchte ich die erste "SW.Blocks.CompileUnit" clonen dahinter einfügen.
Die XML:
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V1.6" />
<DocumentInfo>
</DocumentInfo>
<SW.Blocks.FC ID="0">
<AttributeList>
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
</MultilingualText>
<SW.Blocks.CompileUnit ID="4" CompositionName="CompileUnits">
<AttributeList>
</AttributeList>
<ObjectList>
</ObjectList>
</SW.Blocks.CompileUnit>
<SW.Blocks.CompileUnit ID="B" CompositionName="CompileUnits">
<ObjectList>
</ObjectList>
</SW.Blocks.CompileUnit>
<MultilingualText ID="12" CompositionName="Title">
<ObjectList>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Blocks.FC>
</Document>
Und meine Powershell:
$ObjName=('V15','M18')
$OPN_in ='C:\OPN_2\OPN_Test.xml'
$OPN_Out='C:\OPN_2\OPN_OUT.xml'
# xml Objekt erstellen
$xml = New-Object XML
# xml laden
$xml.Load($OPN_in)
$Urxml = $xml.Clone()
#Alle Grund-Nodes erfassen
$obj_nodes=$xml.Selectnodes('/Document/SW.Blocks.FC/ObjectList')
$obj_nodes.count # gibt eine 1 aus obwohl ich 4 erwarten würde
$obj_nodes
# Abfrage des ersten 'SW.Blocks.CompileUnit' Knotens
$Urnode = $xml.SelectSingleNode("//SW.Blocks.CompileUnit")
# abbrechen wenn kein Knoten gefunden wurde.
if (!$Urnode){
throw "Error, 'SW.Blocks.CompileUnit' Node not found!"
exit 1
}
$z=0
foreach($Obj in $objName)
{
$newnode = $Urnode.Clone()
# id anpassen
$z+=1
$newnode.Id = (100*$z).ToString()
# hänge den kopierten Knoten im selben Parent wie vom Original wieder ins XML ein
[void]$Urnode.ParentNode.AppendChild($newNode)
}
#Letztes Element anfügen
$DelNote= $Xml.SelectNodes("/Document/SW.Blocks.FC/ObjectList/MultilingualText[@CompositionName='Title']")
$EndNode = $DelNote.clone()
#$DelNote.ParentNode
$DelNote.ParentNode.RemoveChild($DelNote) | Out-Null #Fehlermeldung
$EndNode.Count
[void]$Urnode.ParentNode.AppendChild($EndNode)
#$Tempnode.ParentNode.AppendChild($Tempnode)
# speichere das geänderte xml unter neuem Namen
$xml.Save($OPN_Out)
FehlerMeldung:
Das Argument "0" mit dem Wert "System.Xml.XPathNodeList" für "RemoveChild" kann nicht in den Typ "System.Xml.XmlNode" konvertiert werden: "Der Wert
"System.Xml.XPathNodeList" vom Typ "System.Xml.XPathNodeList" kann nicht in den Typ "System.Xml.XmlNode" konvertiert werden."
In C:\Mailbox\01_Projekte\Roskow\Node_anfügen.ps1:47 Zeichen:1
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
"System.Xml.XPathNodeList" vom Typ "System.Xml.XPathNodeList" kann nicht in den Typ "System.Xml.XmlNode" konvertiert werden."
In C:\Mailbox\01_Projekte\Roskow\Node_anfügen.ps1:47 Zeichen:1
$DelNote.ParentNode.RemoveChild($DelNote) | Out-Null
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ( , MethodException+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Wie kann ich die Fehlermeldung beheben bzw. den letzten Node Löschen bzw. die Newnode an einer bestimmten Position einfügen?
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 1321169535
Url: https://administrator.de/contentid/1321169535
Ausgedruckt am: 19.12.2024 um 10:12 Uhr
5 Kommentare
Neuester Kommentar
Dafür gibt's die
XmlNode.InsertAfter(XmlNode, XmlNode) Methode
XmlNode.InsertAfter(XmlNode, XmlNode) Methode
$DelNote.ParentNode.RemoveChild($DelNote)
Tja, schau doch mal genau hin, in $DelNote (Lach , wieder so ein typischer Vertipper für die du hier bekannt bist) wählst du mit SelectNodes mehrere Knoten aus, aber die RemoveChild Methode kann wie der Name doch schon vermuten lässt immer nur einen einzelnen Knoten löschen, du übergibst aber eine Liste vom Typ System.Xml.XPathNodeList du mit SelectNodes ausgewählt hast. Willst du mehrere Knoten löschen itterierst du über die Liste der Knoten und löschst dann das Objekt in der Schleife.$delnodes = $Xml.SelectNodes("/Document/SW.Blocks.FC/ObjectList/MultilingualText[@CompositionName='Title']")
foreach($delnode in $delnodes){
$delnode.ParentNode.RemoveChild($delnode)
}
Zitat von @SPSman:
Leider sehe weder einen Schreibfehler, noch wähle ich nach meinem Verständnis mehr als 1 Node aus:
Kannst du mir erklären wo mein Denkfehler ist?
Ja, dein Denkfehler liegt darin das egal ob es einer oder mehrere Knoten sind die zurückgegeben werden, die SelectNodes()-Methode immer ein Objekt vom Typ System.Xml.XPathNodeList ausgibt, aber RemoveChild ein Objekt vom Typ System.Xml.XmlNode erwartet, z.B. der von SelectSingleNode oder einen einzelnen Knoten einer SelectNodes Liste indem man diesen explizit mittels Index aus der Liste auswählt ....SelectNodes(".....") ! Steht doch schon in der Fehlermeldung wenn man sie denn mal lesen würde Leider sehe weder einen Schreibfehler, noch wähle ich nach meinem Verständnis mehr als 1 Node aus:
Kannst du mir erklären wo mein Denkfehler ist?
Powershell arbeitet objektorientiert und dazu gehören explizit definierte Objektklassen die du einhalten musst und das tust du hier nun mal nicht!
Hier ist wohl mal dringend ein Grundkurs fällig, Powershell Leitfaden für Anfänger