首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Powershell向XML文件添加

使用Powershell向XML文件添加
EN

Stack Overflow用户
提问于 2022-10-21 19:17:57
回答 2查看 100关注 0票数 1

首先,我的编码/脚本技能是30岁.所以这里完全是新手。但不得不处理一些XML。到目前为止,我在这里所做的一切,都还没有达到100%。

(下面是编出来的,当然,我希望没有任何打字.)

情况就是这样。我有多个文件:

  • library1.xml
  • library2.xml
  • etc

每个文件都有每个库的清单,如下所示:

library1.xml

代码语言:javascript
运行
复制
<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

代码语言:javascript
运行
复制
<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,等等。我找到了一个通过解析文件名来实现这一点的脚本。

代码语言:javascript
运行
复制
$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文件之后,我希望获得的输出是:

代码语言:javascript
运行
复制
<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添加到适当的文件中,但只添加到每个文件中的最后一本书中:

代码语言:javascript
运行
复制
<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 (我以前从未使用过),所以我朝那个方向走了.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-22 11:40:45

如果要向每个文件中的节点添加节点,并包含文件本身的BaseName,只需执行以下操作

代码语言:javascript
运行
复制
$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

代码语言:javascript
运行
复制
<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

代码语言:javascript
运行
复制
<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>
票数 1
EN

Stack Overflow用户

发布于 2022-10-21 20:19:38

这是一个很好的问题,有很多方法可以做到。

您目前正在做的是"C#"ish处理方法:使用[XmlElement]类手工创建元素。这将工作,但最终是更多的代码,意图在许多情况下。

另一个我们可以接近的方法是修改我们找到的XML。

代码语言:javascript
运行
复制
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)
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74158287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档