首先,我的編碼/腳本技能已經 30 歲了......所以這里是新手。但是被迫處理一些XML。到目前為止我所做的一切都在這里找到,但還不是 100%。
(以下是編的,當然希望沒有錯別字...)
這是情況。我有多個檔案:
- 庫1.xml
- 庫2.xml
- ETC
每個檔案都有每個庫的清單,如下所示:
庫1.xml
<books>
<book>
<title>Tale of Two Cities</title>
<author>Charles Dickens</author>
</book>
<book>
<title>Lord of the Flies</title>
<author>William Golding</author>
</book>
</books>
庫2.xml
<books>
<book>
<title>The Red Badge of Courage</title>
<author>Stephen Crane</author>
</book>
<book>
<title>The Grapes of Wrath</title>
<author>John Steinbeck</author>
</book>
</books>
我已經找到并調整了將這些合并到 1 個檔案中并保持 XML 結構正確的腳本。
但在合并它們之前,我希望它添加它所在的庫。庫 1、2 等。我找到了一個通過決議檔案名來執行此操作的腳本。
$files = ls *.xml
foreach ($file in $files) {
[xml]$contents = gc $file.fullname
$xmlelement_file = $contents.CreateElement('library')
$xmlelement_file.InnerText = $file.basename
$contents.books.book.AppendChild($xmlelement_file)
$contents.Save($file.fullname)
}
在處理 library1.xml 檔案后,我希望得到的輸出是:
<books>
<book>
<title>Tale of Two Cities</title>
<author>Charles Dickens</author>
<library>library1</library>
</book>
<book>
<title>Lord of the Flies</title>
<author>William Golding</author>
<library>library1</library>
</book>
</books>
然后對其他檔案進行類似的操作。
但是,當我運行它時,生成的檔案將 library1 和 library2 添加到適當的檔案中,但僅添加到每個檔案中的最后一本書:
<books>
<book>
<title>Tale of Two Cities</title>
<author>Charles Dickens</author>
</book>
<book>
<title>Lord of the Flies</title>
<author>William Golding</author>
<library>library1</library>
</book>
</books>
我在想我需要另一個回圈來遍歷每本書,但無法弄清楚。
任何幫助,將不勝感激!
(我實際上更喜歡在 Bash 與 Powershell 中完成所有這些操作,因為我首先通過 Linux 系統上的 API 呼叫獲取 XML 檔案。但我通過 Google 發現的唯一命中是在 Powershell 中(我有今天之前從未使用過),所以我朝那個方向去了......)
uj5u.com熱心網友回復:
如果要將節點添加到每個檔案中的節點,包含檔案本身的 BaseName,只需執行
$xml = [System.Xml.XmlDocument]::new()
Get-ChildItem -Path 'D:\Test' -Filter '*.xml' -File | ForEach-Object {
# load the xml file. This way, you are ensured to get the file encoding correct
$xml.Load($_.FullName)
foreach ($book in $xml.books.book) {
$libnode = $xml.CreateElement('library')
$libnode.InnerText = $_.BaseName
[void]$book.AppendChild($libnode)
}
$xml.Save($_.FullName)
}
使用您的示例檔案,您最終會得到
庫1.xml
<books>
<book>
<title>Tale of Two Cities</title>
<author>Charles Dickens</author>
<library>library1</library>
</book>
<book>
<title>Lord of the Flies</title>
<author>William Golding</author>
<library>library1</library>
</book>
</books>
庫2.xml
<books>
<book>
<title>The Red Badge of Courage</title>
<author>Stephen Crane</author>
<library>library2</library>
</book>
<book>
<title>The Grapes of Wrath</title>
<author>John Steinbeck</author>
<library>library2</library>
</book>
</books>
uj5u.com熱心網友回復:
這是一個很好的問題,并且有很多方法可以完成它。
您目前正在做的是“C#”式的做事方式:使用[XmlElement]類手動創建元素。這將起作用,但最終會成為在許多情況下預期的更多代碼。
另一個我們可以解決的方法是修改我們找到的 XML。
Get-ChildItem -Filter *.xml | # Get all XML files (you may want to filter this)
Select-Xml -XPath . | # Get the root node of each file
ForEach-Object {
# Store the node in xPathMatch
$xPathMatch = $_
# and get an escaped version of the filename.
$fileName = [Security.SecurityElement]::Escape("$(
$xPathMatch.Path | Split-Path -Leaf)"
)
# walk over each book in .books
foreach ($bookNode in $xPathMatch.Node.books.book) {
# If there was already a library element,
if ($bookNode.library)
{
# update it's contents.
$bookNode.library = "$fileName"
} else
{
# If there was not, create one.
$bookNode.innerXml = "<library>$($fileName)</library>"
}
}
# At this point all of the nodes have been changed,
# so the last thing for us to do is .Save
$xPathMatch.Node.Save($xPathMatch.Path)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/521266.html
標籤:xml电源外壳
下一篇:XPath選擇沒有子元素的元素?
