无法使用 powershell 在 xml 中添加新元素

Unable to add a new element in xml using powershell

我正在尝试使用 powershell 在我的 xml 文件中添加一个新元素。

XML 文件(不能更改当前内容,只能在语言下添加新元素):

<UserSettings>
  <ApplicationIdentity version="16.0" />
  <Category name="License Header Manager_Languages" Category="{d1b5984c-1693-4f26-891e-0ba3bf5760b4}" Package="{4c570677-8476-4d33-bd0c-da36c89287c8}" RegisteredName="License Header Manager_Languages" PackageName="LicenseHeadersPackage">
    <PropertyValue name="LanguagesSerialized">&lt;Languages&gt;
  &lt;Language LineComment="//" BeginComment="/*" EndComment="*/" BeginRegion="#region" EndRegion="#endregion" SkipExpression=""&gt;
    &lt;Extensions&gt;
      &lt;Extension&gt;.cs&lt;/Extension&gt;
    &lt;/Extensions&gt;
  &lt;/Language&gt;
  &lt;Language LineComment="'" BeginComment="" EndComment="" BeginRegion="#Region" EndRegion="#End Region" SkipExpression=""&gt;
    &lt;Extensions&gt;
      &lt;Extension&gt;.vb&lt;/Extension&gt;
    &lt;/Extensions&gt;
  &lt;/Language&gt;
  &lt;/Languages&gt;
  </PropertyValue>
 </Category>
</UserSettings>

我正在尝试使用以下代码添加具有不同扩展名的新语言

$file = "C:\Users\TempUser\Downloads\CurrentSettings.xml"

[xml]$xml = Get-Content $file

$extensions = @(
    ,@( @("#", "<#", "#>", ""), @(".ps1", ".psm1"))
    ,@( @("//", "/*", "*/", ""), @(".js", ".ts")))
$AttributeNames = @("LineComment", "BeginComment", "EndComment", "SkipExpression")

$xml.UserSettings.Category.PropertyValue | Where-Object { $_.name -eq "LanguagesSerialized" } | %{ 

    foreach ($elements in $extensions) {
        $lang = $xml.CreateElement("Language")   

        for ($j=0; $j -lt $AttributeNames.length; $j++) {
            $lang.SetAttribute($AttributeNames[$j], $elements[0][$j]) 
        }

        $extsElement = $lang.AppendChild($xml.CreateElement("Extensions"))
            
        foreach($ext in $elements[1]){
            $extElement = $extsElement.AppendChild($xml.CreateElement("Extension"))
            $extElement.AppendChild($xml.CreateTextNode($ext))
        }

        $_.AppendChild($lang)
    }
      
}

$xml.Save($file)

预期结果:

  &lt;Language LineComment="#" BeginComment="@*" EndComment="*@" BeginRegion="" EndRegion="" SkipExpression=""&gt;
    &lt;Extensions&gt;
      &lt;Extension&gt;.ps1&lt;/Extension&gt;
      &lt;Extension&gt;.psm1&lt;/Extension&gt;
    &lt;/Extensions&gt;
  &lt;/Language&gt;

文件中的当前输出(它在 Languages 标签后添加元素):

&lt;/Language&gt;
&lt;/Languages&gt;<Language LineComment="#" BeginComment="<#" EndComment="#>" SkipExpression=""><Extensions><Extension>.ps1</Extension><Extension>.psm1</Extension></Extensions></Language><Language LineComment="//" BeginComment="/*" EndComment="*/" SkipExpression=""><Extensions><Extension>.js</Extension><Extension>.ts</Extension></Extensions></Language></PropertyValue>
    <PropertyValue name="Version">3.0.3</PropertyValue>
  </Category>
</UserSettings>

感谢任何帮助,谢谢!

问题是你的输入 xml 是混合的——它有 xml 编码和非编码字符(这就是你得不到 PropertyValue 标签的子节点的原因) .我需要将其更改为所有 xml 非编码(< 和 >)。之后就成功了。

    <UserSettings>
    <ApplicationIdentity version="16.0" />
    <Category name="License Header Manager_Languages" Category="{d1b5984c-1693-4f26-891e-0ba3bf5760b4}" Package="{4c570677-8476-4d33-bd0c-da36c89287c8}" RegisteredName="License Header Manager_Languages" PackageName="LicenseHeadersPackage">
      <PropertyValue name="LanguagesSerialized">
        <Languages>
          <Language LineComment="//" BeginComment="/*" EndComment="*/" BeginRegion="#region" EndRegion="#endregion" SkipExpression="">
            <Extensions>
              <Extension>.cs</Extension>
            </Extensions>
          </Language>
          <Language LineComment="'" BeginComment="" EndComment="" BeginRegion="#Region" EndRegion="#End Region" SkipExpression="">
            <Extensions>
              <Extension>.vb</Extension>
            </Extensions>
          </Language>
        </Languages>
      </PropertyValue>
    </Category>
  </UserSettings>

在这个过程中,我修改了你的文件以使用 XPath(只是因为它对我来说更容易):

      $file = "C:\temp\test.xml"

  [xml]$xml = Get-Content $file

  $extensions = @(
      ,@( @("#", "<#", "#>", ""), @(".ps1", ".psm1"))
      ,@( @("//", "/*", "*/", ""), @(".js", ".ts")))
  $AttributeNames = @("LineComment", "BeginComment", "EndComment", "SkipExpression")



      $languages = $xml.SelectSingleNode("//UserSettings/Category/PropertyValue[@name='LanguagesSerialized']/Languages")
      foreach ($elements in $extensions) {
         
          $lang = $xml.CreateElement("Language")   
          

          for ($j=0; $j -lt $AttributeNames.length; $j++) {
              $lang.SetAttribute($AttributeNames[$j], $elements[0][$j]) 
          }

          $extsElement = $lang.AppendChild($xml.CreateElement("Extensions"))
              
          foreach($ext in $elements[1]){
              $extElement = $extsElement.AppendChild($xml.CreateElement("Extension"))
              $extElement.AppendChild($xml.CreateTextNode($ext))
          }

           
           $languages.AppendChild($lang)
      }
      
        



  $xml.Save($file)

谢谢大家!就我而言,我无法在文件中编码并另存为 <>,因为这是另一个解析器的工作。在进入此解析器之前,我必须添加语言。以前,我在主语言节点外添加子元素。这是将子语言节点添加到主语言节点的更新解决方案。

$file = "C:\Users\TempUser\Downloads\CurrentSettings.xml"
[xml]$xml = Get-Content $file
$extensions = @(
    ,@( @("#", "<#", "#>", ""), @(".ps1", ".psm1"))
    ,@( @("//", "/*", "*/", ""), @(".js", ".ts")))
$AttributeNames = @("LineComment", "BeginComment", "EndComment", "SkipExpression")

$xml.UserSettings.Category.PropertyValue | Where-Object { $_.name -eq "LanguagesSerialized" } | %{
    [xml]$Settings = $_.'#text' 

    foreach ($elements in $ExtensionDetails) {
        $lang = $Settings.CreateElement("Language")   
        for ($j=0; $j -lt $AttributeNames.length; $j++) {
            $lang.SetAttribute($AttributeNames[$j], $elements[0][$j]) 
        }

        $extsElement = $lang.AppendChild($Settings.CreateElement("Extensions")) 
        foreach($ext in $elements[1]){
            $extElement = $extsElement.AppendChild($Settings.CreateElement("Extension"))
            $extElement.AppendChild($Settings.CreateTextNode($ext))
        }
        $Settings.Languages.AppendChild($lang)
    } 
    $_.'#text' = $Settings.InnerXml
}

$xml.Save($file)

输出是

    ...
    ...
    &lt;/Language&gt;
    &lt;Language LineComment="#" BeginComment="@*" EndComment="*@" SkipExpression=""&gt;
    &lt;Extensions&gt;
        &lt;Extension&gt;.ps1&lt;/Extension&gt;
        &lt;Extension&gt;.psm1&lt;/Extension&gt;
    &lt;/Extensions&gt;
    &lt;/Language&gt;
    &lt;Language LineComment="//" BeginComment="/*" EndComment="*/" SkipExpression=""&gt;
    &lt;Extensions&gt;
        &lt;Extension&gt;.js&lt;/Extension&gt;
        &lt;Extension&gt;.ts&lt;/Extension&gt;
    &lt;/Extensions&gt;
    &lt;/Language&gt;
&lt;/Languages&gt;