---
# System prepended metadata

title: python xml 的CRUD處理 用在 AI影像標註2

---

# python xml 的CRUD處理 用在 AI影像標註2
---

前置學習:
[Python argparse 教學：比 sys.argv 更好用，讓命令列引數整潔又有序](https://haosquare.com/python-argparse/)

檔案位置: https://drive.google.com/drive/folders/1ORXhxrOXyHKQ9HvkS0dvmKb4rn5SgCg5?usp=sharing


1. [xml_node_rename.py 更改標註名稱](#1-更改標註名稱)
2. [xml_node_move.py 置換劣化節點](#2-置換劣化節點)
3. [files_dispatch.py 資料夾比對](#3-資料夾比對)

---

## 1. 更改標註名稱

xml_node_rename.py

需求:
1. 指定資料夾路徑,舊劣化名稱、新劣化名稱
2. 把資料夾內的 .xml 檔內的舊劣化名稱置換成新劣化名稱
3. 防呆: 
```
        若原本的劣化有 crack_01 efflorescence,更名時誤下指令 把 crack_01 更名成 efflorescence 而不是原本要換的 crack_fissures,
        會造成更名後的 efflorescence(實際上是裂縫龜裂) 和原本已經有的 efflorescence(白華) 混在一起,變成全部都必須重新人工標註修正,
        因此需要在更名時,若更改名稱和已有的劣化名稱重疊,需提示 
```
4. 注意事項!!: (!!注意!! 程式無法判斷,所以須正確下指令或是一次執行指處理一個劣化名稱比較保險)
```
        下指令時 --old_tag 和 --new_tag 項目需前後對照順序一致
        例如.
        (O)正確的例子
        ` --old_tag crack_01 water_gain --new_tag crack_fissures infiltration_crack` 
        crack_01 對到 crack_fissures, water_gain 對到 infiltration_crack
        (X) 錯誤的例子
        --old_tag crack01 water_gain --new_tag infiltration_crack crack_fissures
        crack_01 對到 infiltration_crack, water_gain 對到 crack_fissures
```
程式:
- 選取資料夾路徑(GUI或手動填)-手動填 , 指定舊劣化名稱、新劣化名稱
- 遍歷選取資料夾讀取 .xml 檔,取得劣化資訊
- 防呆: 比對劣化資訊,若更改名稱是已存在劣化標註,就詢問確認
- 更換指定的舊的劣化類別名稱,並寫入到 .xml 檔


使用:
- 安裝套件 : 不需安裝,使用內建lib
- 執行 python:
```
    下面指令會把 --path 資料夾內的 --old_tag 舊劣化名稱  置換成 --new_tag 新劣化名稱
    > python3 xml_node_rename.py --path "資料夾路徑" --old_tag "舊劣化名稱" --new_tag "新名稱"
    > python3 xml_node_rename.py --path D:\labelImg提交檔案 --old_tag crack_01 water_gain --new_tag crack_fissures infiltration_crack
    可以把上面的 --path --old_tag --new_tag 換成簡寫的 -p -o -n ,如下所示
    > python3 xml_node_rename.py -p     D:\labelImg提交檔案 -o        crack_01 water_gain -n        crack_fissures infiltration_crack
```
指令參數說明：
```
    -p, --path
        指定被置換掉的 .xml 檔案所在的資料夾路徑,例如. `D:\labelImg提交檔案`
    -o, --old_tag
        要被置換掉的劣化類別名稱,例如. crack_01
    -n, --new_tag
        用來置換的調劣化類別名稱,例如. crack_fissures
```
- 將 old 資料夾的 .xml檔內的特定劣化節點名稱(e.g. <crack_01> ) 換成新名稱(e.g. <crack_fissures>)


---
## 2. 置換劣化節點

xml_node_move.py

需求:
1. 指定 old xml 和 new xml 路徑 (檔名相同) 及更動的劣化類別
2. 新建 xml,裏面包含  old xml 移除特定劣化類別節點 (ex. <crack>)後,把 new xml 特定劣化類別節點 append 到 old xml ,放到 replaced 資料夾

程式:
- 選取新、舊資料夾路徑(GUI或手動填)-手動填 , 指定劣化類別
- 遍歷選取資料夾讀取 .xml 檔
- 新建空xml,裡面包含移除舊的劣化類別節點,將更動的劣化類別節點複製,並寫入到舊的 .xml 放到 replaced 資料夾(沒有更動 old xml 和 new xml)

使用:
- 安裝套件 : 不需安裝,使用內建lib
- 執行 python:
```
    @ 置換劣化類別:
    下面指令會使用 --new_folder 資料夾內的指定劣化類別節點 --deteriorate , 替代掉 --old_folder 內的指定劣化類別節點
    > python3 xml_node_move.py --deteriorate crack efflorescence --old_folder "要被置換的舊節點資料夾路徑" --new_folder "新節點資料夾路徑"

    可以把上面的 --deteriorate --old_folder --newfolder 換成簡寫的 -d -o -n ,如下所示（空格是為了和上面清楚對照可以不需要這麼多空格) 
    > python3 xml_node_move.py -d            crack efflorescence -o           "要被置換的舊節點資料夾路徑" -n           "新節點資料夾路徑"

    @ 保留劣化類別:
    下面指令會使用 --new_folder 資料夾內的指定保留劣化類別以外的所有節點 --keep_deteriorate , 替代掉 --old_folder 內的指定劣化類別節點
    > python3 xml_node_move.py --keep_deteriorate crack efflorescence --old_folder "要被置換的舊節點資料夾路徑" --new_folder "新節點資料夾路徑"

    可以把上面的 --keep_deteriorate --old_folder --newfolder 換成簡寫的 -k -o -n ,如下所示（空格是為了和上面清楚對照可以不需要這麼多空格) 
    > python3 xml_node_move.py -k            crack efflorescence -o           "要被置換的舊節點資料夾路徑" -n           "新節點資料夾路徑"
```
指令參數說明：
```
    -d 置換劣化節點 和 -k 保留劣化節點 是互斥選項,無法同時執行
    -d, --deteriorate  
        指定要置換的劣化類別,可指定一個到多個,例如. `-d crack` 或 `-d crack efflorescence`,這些劣化類別的節點會被置換掉
    -k, --keep_deteriorate
        指定保留的劣化類別,可指定一個到多個, 例如. `-k crack` 或 `-k crack efflorescence`,除了指定的劣化類別外都會置換成新的版本
    
    -o, --old_folder
        要被置換掉的 .xml 檔案所在的資料夾路徑,例如. `D:\labelImg提交檔案`
    -n, --new_folder
        用來置換的調整過後的新劣化節點的 .xml 檔所在的資料夾路徑,例如. `D:\labelImg提交檔案\白華_efflorescence`
```
- 將 old 資料夾的 .xml檔內的特定劣化節點資訊(e.g. <crack>附帶的框選位置尺寸資訊) 換成 new 資料夾的 .xml檔的劣化節點資訊

---
## 3. 資料夾比對

files_dispatch.py

需求:
1. 指定 現在資料夾路徑 和 對照用的資料夾路徑 進行比對 .xml .jpg 檔案
2. 把比對符合 對照用資料夾 內的檔案存放到 matched 資料夾,不符合的放到 unmatched 資料夾,把剩下的 .xml .jpg 檔案存放到 other 資料夾
3. 產生 紀錄有比對符合 matched 和比對不存在的(對照資料夾有但現有資料夾沒有) unmatched 列表的 .csv 檔案(方便用 excel 匯入查看確認)

@ 紀錄有比對符合 matched 和比對不存在的(對照資料夾有但現有資料夾沒有) unmatched 列表的 .csv 檔案
![csv檔](https://i.imgur.com/bP9tBW2.png)
    
@ csv檔的內文如下:
![csv檔內容](https://i.imgur.com/H8rsRYt.png)
    
@excel匯入.csv檔時,使用 UTF-8 編碼 (這邊用LibreOffice excel 畫面示意,沒有Microsoft excel)
![](https://i.imgur.com/3cpKyGu.png)

@ 匯入excel 後方便確認比對符合和比對不符合的(對照資料夾有但現有資料夾沒有)檔案
![](https://i.imgur.com/kCAN11w.png)

程式:
- 選取新、舊資料夾路徑(GUI或手動填)-手動填
- 比對 對照資料夾 和 原資料夾是否有相符的檔案,並移動 .jpg .xml 檔案到 matched 資料夾和 unmatched 資料夾
- 寫入比對符合和比對不存在的(對照資料夾有但現有資料夾沒有)檔案名稱到 .csv檔方便確認
- 將比對完移動後,剩下來的 .jpg .xml 檔案移動到 other 資料夾 

使用:
- 安裝套件 : 不需安裝,使用內建lib
- 執行 python:
```
    下面指令會把 --path 資料夾內.jpg .xml 檔, 比對 --cpath  內的檔案,符合的放到 matched 資料夾,
    不符合的放到 unmatched 資料夾,剩下的放到 other 資料夾 
    > python3 files_dispatch.py --path "現在資料夾路徑" --cpath  "對照資料夾路徑"
    例如.
    > python3 files_dispatch.py --path D:\labelImg提交檔案 --cpath  D:\labelImg提交檔案\對照資料夾

    可以把上面的 --path --cpath 換成簡寫的 -p -c ,如下所示（空格是為了和上面清楚對照可以不需要這麼多空格) 
    > python3 files_dispatch.py -p     "現在資料夾路徑" -c       "對照資料夾路徑"
    例如.
    > python3 files_dispatch.py -p D:\labelImg提交檔案 -c D:\labelImg提交檔案\對照資料夾
```
指令參數說明：
```
    -p, --path 
        現在資料夾 路徑,例如. `D:\labelImg提交檔案`
    -c, --cpath
        用來比對用的 .xml 檔所在的 對照資料夾 路徑,例如. `D:\labelImg提交檔案\對照資料夾`
```
