การแก้ไข xml ด้วย powershell
การแก้ไขข้อมูลในไฟล์ xml บน Windows ไม่ใช่เรื่องง่าย ถ้ามีข้อมูลจำนวนมาก และยิ่งถ้ามีหลายไฟล์ ก็ยิ่งทำให้ต้องใช้เวลาในการแก้ไขไม่ใช่น้อย
ปัจจุบัน (2564) คือ Windows PowerShell 7.1.3 ยังไม่มี IDE ต้องใช้ผ่านทาง Command Line เท่านั้น (รุ่นที่ติดมากับ Windows10 ไม่ใช่รุ่นปัจจุบัน ถ้าต้องการใช้ ต้องไป download มาติดตั้งใหม่
ทางออกคือการใช้ PowerShell ซึ่งมีมาแล้วใน Windows สามารถเขียนคำสั่งใน command line หรือจะเขียนเป็น script และสั่งให้ทำงานได้ เช่นกัน นอกจากนี้ ยังมี PowerShell ISE ซึ่งมีหน้าจอให้เขียนคำสั่ง หรือ Script ก็ได้
การเปิดใช้งาน
- คลิกขวาที่ปุ่ม เริ่มต้น และ Windows PowerShell (Admin)
- หรือถ้ามีช่องค้นหา ก็พิมพ์คำว่า PowerShell และเลือกเปิดแบบ Admin (Run as adminstrator)
- ถ้าเป็นการใช้งานครั้งแรก อาจจะมีปัญหาเกี่ยวกับ ExecutionPolicy ให้เปลี่ยน ExecutionPolicy เป็น Unrestricted โดยพิมพ์ ในหน้าของ PowerShell ดังนี้
- เนื่องจาก ExecutionPolicy เป็นการป้องกันเกี่ยวกับความปลอดภัย เพื่อป้องกันไม่ให้โปรแกรมที่เป็นอันตรายต่อเครื่องคอมพิวเตอร์ โปรแกรม PowerShell จะถามให้ยืนยัน ให้คลิก Y
- เมื่อโปรแกรมพร้อม จะเห็นคำว่า PS ให้พิมพ์ชื่อไฟล์ script ที่เขียนไว้ โดยต้องระบุที่อยู่ให้ชัดเจนด้วย แล้วกด enter
- ถ้าไม่มีปัญหาอะไร โปรแกรมจะแสดงเป็น Command Prompt
- แต่ถ้ามี Error โปรแกรมจะแสดงข้อผิดพลาด พร้อมทั้งอธิบายว่า ผิดพลาดอย่างไร บางครั้งก็มีข้อเสนอแนะให้ด้วย
- จากนั้น จึงพิมพ์ชื่อของไฟล์ .ps1 (พร้อมระบุที่อยู่ของไฟล์ .ps1 ให้ถูกต้องด้วย) แล้วกด Enter เพื่อให้ ทำงานตามสคริป
- อีกทางเลือก อาจจะคัดลอกสคริป มาวางไว้ใน หน้าต่างของ PowerShell แล้วกด Enter ก็ได้ เช่น
ตัวอย่าง Script
ใช้ text editor เขียนคำสั่งข้างล่าง และบันทึกไว้ เป็นไฟล์ นามสกุล .ps1
สมมติว่า ต้องการแก้ไข <qNum> ในไฟล์ xml ซึ่งมีโครงสร้างดังนี้
Script:
#ไฟล์ที่ต้องการแก้ไข
$inFile = "D:\_000fromandroid_new\2_th_1_word22.xml"
# ไฟล์ที่แก้ไขแล้ว ถ้าต้องการให้แทนที่ไฟล์เดิม ก็ใช้ชื่อเดิม
$outFile = "D:\_000fromandroid_new\2_th_1_word22_updated.xml"
# Get-Content คือให้อ่านไฟล์ xml เก็บใน memory
$xml = [xml] (Get-Content -Raw $inFile)
# กำหนดค่าที่ต้องการให้เปลี่ยน ในกรณีนี้ เราจะเพิ่มตัวเลขเพื่อไม่ให้ซ้ำกัน
$x=1
#ให้เลือก parent node ของ node ที่จะเปลี่ยน
#และวน โดยใช้ ForEach
$xml.SelectNodes('//thisQuestion').ForEach({
# เปลี่ยนค่าเป็นตัวแปรชนิดข้อความ
$new_qNum = ($x.ToString())
# update ค่าใน <qNum> ซึ่งเป็นลูกของ <thisQuestion>
$_.qNum = $new_qNum
# เพิ่มค่า เพื่อจะได้ไม่ซ้ำกัน
$x++
})
# เสร็จแล้ว บันทึก จะได้ไฟล์ xml ที่แก้ไขแล้ว
$xml.Save($outFile)
ในกรณีที่ต้องการเปลี่ยนครั้งละหลาย ๆ ไฟล์
ให้เอาไฟล์ทั้งหมดไปไว้ในห้อง เดียวกัน และให้เปลี่ยนทุกไฟล์
ตัวอย่าง script
$files = Get-ChildItem "D:\_00tmp\"
$x=1
foreach ($f in $files){
$xml = [xml] (Get-Content -Raw $f)
$xml.SelectNodes('//thisQuestion').ForEach({
$new_qNum = ($first + $x.ToString() + $last)
$_.qNum = $new_qNum
$x++
})
$outfile = $f.FullName #แทนที่ไฟลฺ์เดิม
$xml.Save($outFile)
}
ในกรณีที่ต้องการเปลี่ยนข้อความ ในไฟล์ .txt หรือ html ครั้งละหลาย ๆ ไฟล์ เช่น ต้องการเปลี่ยนจาก คำว่า assets/images/ เป็น images/ ให้นำไฟล์ที่ต้องการเปลี่ยนไปไว้รวมกันในห้องเดียวกัน เช่น ห้อง D:\_01 แล้วเขียนสคริป ดังนี้
$fileNames = Get-ChildItem "D:\_01" -Recurse |
select -expand fullname
foreach ($filename in $filenames)
{
( Get-Content $fileName) -replace 'assets/images/', 'images/' | Set-Content $fileName
}
ข้อมูลจาก
https://stackoverflow.com/questions/47336537/finding-and-updating-xml-node-in-powershell
ความคิดเห็น
แสดงความคิดเห็น