erainer
Goto Top

Frage zu Namespaces XML und SelectSingleNode

Hallo
Ich habe mittlerweile folgendes Script

$oldfile = "C:\Users\H50BYSA\Downloads\file\file_xml_verify.xml"
$newfile = "C:\Users\H50BYSA\Downloads\file\file_verify1.xml"
$xml = [XML](Get-Content -Path $oldfile)
$newchild = $xml.CreateElement("tag3")
$newChild.InnerText = $xml.gruppe1.untergruppe1.tag2
$node = $xml.SelectSingleNode('/gruppe1/untergruppe1/tag2')
$node.ParentNode.InsertAfter($newChild,$node)
$xml

Leider klappt bei mir genau dieser Teil nicht

$node = $xml.SelectSingleNode('/gruppe1/untergruppe1/tag2')

denn auf
$node.ParentNode.InsertAfter($newChild,$node)
bekomme ich

You cannot call a method on a null-valued expression.

Zum Hinweis mein XML sieht wie folgt aus stark schematisiert

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="sheet-verify.xslt"?><nsp1:gruppe1 version="2.0" xsi:schemaLocation="pfad auf xsd" xmlns:nsp2 pfad auf die Namespaces ....
<nsp2:untergruppe1><nsp3:tag1>111111</nsp3:tag1><nsp3:tag2>22222</nsp3:tag2><nsp3:tag4>22222</nsp3:tag4></nsp2:untergruppe1>
<nsp2:untergruppe1><nsp4:tag1/> ............</nsp2:untergruppe1>
</nsp1:gruppe1>

also meine Tags haben im XML alle einen Namespace

hat jemand eine Idee warum der Xpath nicht klappt
haeb es auch versucht mit nur '/' oder '/gruppe1' aber immer bekomme ich den Null Value

Danke für die Hilfe

Content-ID: 547258

Url: https://administrator.de/contentid/547258

Ausgedruckt am: 24.11.2024 um 18:11 Uhr

BirdyB
BirdyB 14.02.2020 um 09:33:58 Uhr
Goto Top
Sei doch so gut und packe deinen Code in die Code-Tags. Das macht es wirklich besser lesbar.
Ausserdem hast du da eine Zeile:
$node =
Da fehlt doch was... Es muss schon was in der Variable drin sein, die du einfügen willst...
ERainer
ERainer 14.02.2020 um 09:45:54 Uhr
Goto Top
Hallo BirdyB,

der variable $node wird doch versucht mit
$xml.SelectSingleNode('XPATH')  
$node = $xml.SelectSingleNode('\')  

etwas zuzuweisen ( aber egal wie mein XPATH aussieht) $node scheint Null zu bleiben
bin bezüglich powershell scripts ein ziemlicher nooB
aber ich dachte mit
$node = $xml.SelectSingleNode('\')  
weise ich der Variable $node was zu

also sollte
$oldfile = "C:\Users\H50BYSA\Downloads\file\file_xml_verify.xml"  
$newfile = "C:\Users\H50BYSA\Downloads\file\file_verify1.xml"  
$xml = [XML](Get-Content -Path $oldfile)
$newchild = $xml.CreateElement("tag3")  
$newChild.InnerText = $xml.gruppe1.untergruppe1.tag2
$node = $xml.SelectSingleNode('/gruppe1/untergruppe1/tag2')  
$node.ParentNode.InsertAfter($newChild,$node)
$xml

hier kein Null in $node sein
142970
Lösung 142970 14.02.2020 aktualisiert um 10:23:20 Uhr
Goto Top
Musst du mit einem Namespace-Manager arbeiten und im XPath die Selektoren anpassen und den Namespacemanager der Abfrage als Parameter übergeben, das neue Element muss natürlich auch mit dem entsprechenden Namespace erstellt werden ...
# Beispiel XML Object erzeugen
$xml = [xml]@"  
<?xml version="1.0" encoding="UTF-8"?>  
<?xml-stylesheet type="text/xsl" href="sheet-verify.xslt"?>  
<nsp1:gruppe1 version="2.0" xmlns:nsp1="http://nsp1.com" xmlns:nsp2="http://nsp2.com" xmlns:nsp3="http://nsp3.com">  
    <nsp2:untergruppe1>
        <nsp3:tag1>111111</nsp3:tag1>
        <nsp3:tag2>22222</nsp3:tag2>
        <nsp3:tag4>22222</nsp3:tag4>
    </nsp2:untergruppe1>
</nsp1:gruppe1>
"@  

# Namespace-Manager und Namespaces hinzufügen
[System.Xml.XmlNamespaceManager]$ns = new-Object System.Xml.XmlNamespaceManager $xml.NameTable
$ns.AddNamespace("nsp1","http://nsp1.com")  
$ns.AddNamespace("nsp2","http://nsp2.com")  
$ns.AddNamespace("nsp3","http://nsp3.com")  


# erstelle Element mit Inhalt
$newchild = $xml.CreateElement("nsp3:tag3","http://nsp3.com")  
$newChild.InnerText = "WertDEF"  

# Wähle den Referenzknoten mit XPath aus
$node = $xml.SelectSingleNode('/nsp1:gruppe1/nsp2:untergruppe1/nsp3:tag2',$ns)  

# füge den neuen Knoten nach dem Referenzknoten ein
$node.ParentNode.InsertAfter($newChild,$node) | out-null

# Gib nur zur Anschauung den XML Code aus
$xml.OuterXml

p.s. Wieso extra ein neuer Thread dafür??? Du hättest einfach im Thread von gestern die ergänzende Frage dazu stellen können, aber du hast ja noch nicht mal freundliche Rückmeldung gegeben face-sad! Hier sitzen immerhin noch Leute und keine Roboter die sich deiner Frage annehmen! DANKE.
Kraemer
Kraemer 14.02.2020 um 10:09:27 Uhr
Goto Top
Moin,

lass dir mal folgendes ausgeben:

$xml.gruppe1.untergruppe1.tag2 | get-member

Vielleicht kommst du dann darauf
BirdyB
BirdyB 14.02.2020 um 11:49:03 Uhr
Goto Top
Moin,

sorry, ohne die Code-Tags macht das Smartphone dann Umbrüche wo keine hingehören.
Daher sah es so aus, als fehlte da etwas...

VG
ERainer
ERainer 18.02.2020 aktualisiert um 11:40:04 Uhr
Goto Top
Hallo
Danke für die tolle Hilfe bis jetzt
Leider habe ich jetzt noch ein Problem bei dem ich auf dem Schlauch stehe
ich habe jetzt folgendes Codesnippet bei dem ich noch ein Problem habe
#Xml einlesen
$xml = [XML](Get-Content -Path $oldfile)
$reports = $xml.root.Hauptgruppe1.Untergruppe2.SelectNodes("ftc:UnterUntergruppe",$ns)  
foreach ($report in $reports)
{
$report.UnterUnterUntergruppe.AppendChild($newchild4)
$report.UnterUnterUntergruppe.OuterXml
$report.
}
$xml.Save($newfile)

Wenn ich mir den Teil auf der variable $report ansehe dann sieht es Korrekt aus mein neues Kindelement wurde erzeugt und wird mir angezeigt
wenn ich dann das XML zurückspiele (als neue Datei - dann ist diese Änderung leider nicht vorhanden ) ich bekomme auch keinen Fehler
wie bekomme ich das nun hin dass die Änderung die ich bei OuterXML sehe dann auch wieder in das XML zurückgeschrieben wird ?
Update:
habe gerade festgetsellt dass er schon zurückschreibt aber nur in das letzte Vorkommnis
also im letzten Element wurde es angelegt hat ich will es aber eigentlich in jedem Vorkommnis anlegen
zumindest dieser Teil meines Codes verhält sich so wenn ich das statt dem AppendChild mache
wenn er es nun bei jedem Vorkommnis machen würde anstatt nu beim letzten wäre es super
$node4 = $report.SelectSingleNode("./nsp1:UnterUnterUntergruppe//nsp1:Tag2",$ns)  
$node4.ParentNode.InsertAfter($newChild4,$node4) | Out-Null
LG