首先,我的编码/脚本技能是30岁.所以这里完全是新手。但不得不处理一些XML。到目前为止,我在这里所做的一切,都还没有达到100%。
(下面是编出来的,当然,我希望没有任何打字.)
情况就是这样。我有多个文件:
每个文件都有每个库的清单,如下所示:
library1.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>
library2.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>
我已经找到并调整了将这些脚本合并到一个文件中并保持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 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>
其他文件也是类似的。
但是,当我运行此操作时,生成的文件将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文件的。但我在谷歌上找到的唯一点击是Powershell (我以前从未使用过),所以我朝那个方向走了.
发布于 2022-10-22 11:40:45
如果要向每个文件中的节点添加节点,并包含文件本身的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>
发布于 2022-10-21 20:19:38
这是一个很好的问题,有很多方法可以做到。
您目前正在做的是"C#"ish处理方法:使用[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://stackoverflow.com/questions/74158287
复制相似问题