Добавление строки в XML с пробелом

#xml #powershell

#xml #powershell

Вопрос:

У меня есть этот XML

     <application>
  <component name="UpdatesConfigurable">    
    <enabledExternalComponentSources>
      <item value="Android SDK" />
    </enabledExternalComponentSources>
    <option name="externalUpdateChannels">
      <map>
        <entry key="Android SDK" value="Stable Channel" />
      </map>
    </option>
    <knownExternalComponentSources>
      <item value="Android SDK" />
    </knownExternalComponentSources>
    <option name="LAST_BUILD_CHECKED" value="IU-202.7660.26" />
    <option name="LAST_TIME_CHECKED" value="1606406082514" />
  </component>
</application>
  

Мне нужно добавить

 <option name="CHECK_NEEDED" value="false" />
  

Затем получение:

     <application>
  <component name="UpdatesConfigurable">
    <option name="CHECK_NEEDED" value="false" />
    <enabledExternalComponentSources>
      <item value="Android SDK" />
    </enabledExternalComponentSources>
    <option name="externalUpdateChannels">
      <map>
        <entry key="Android SDK" value="Stable Channel" />
      </map>
    </option>
    <knownExternalComponentSources>
      <item value="Android SDK" />
    </knownExternalComponentSources>
    <option name="LAST_BUILD_CHECKED" value="IU-202.7660.26" />
    <option name="LAST_TIME_CHECKED" value="1606406082514" />
  </component>
</application>
  

Я создал этот скрипт:

     $fileName = “C:sovgardeupdates.xml”;
$xml = [System.Xml.XmlDocument](Get-Content $fileName);

$child = $xml.CreateElement('option name')
$child.SetAttribute('CHECK_NEEDED','false')
$node = $xml.SelectSingleNode('component name')
$node.AppendChild($child)
  

Но ошибка при «имени параметра»…

Как добавить эту строку, если она еще не существует. Я считаю, что проблема в пространстве.

Спасибо,

Комментарии:

1. Для вашей задачи лучше использовать XSLT и его так называемое преобразование идентификаторов .

2. Ваш код пытается создать элемент с именем ‘option name’, но фактический элемент называется просто ‘option’. Пробелы не допускаются в именах элементов XML, поэтому ‘name’ фактически является первым атрибутом. Вы должны установить два атрибута.

3. zett42 Я не уверен, что понимаю. Как мне установить второй атрибут, а затем сохранить правильную информацию в этой строке?

4. Ицхак Хабинский У вас есть пример?

5. usingxml.com/Transforms/XslIdentity

Ответ №1:

Имя элемента option — нет option name .

Вам нужно создать элемент с именем option , а затем вы хотите создать два атрибута. Один атрибут name со значением «CHECK_NEEDED», а другой атрибут check со значением «false»

 $fileName = “C:sovgardeupdates.xml”;
$xml = [System.Xml.XmlDocument](Get-Content $fileName);

$child = $xml.CreateElement('option')
$child.SetAttribute('name', 'CHECK_NEEDED')
$child.SetAttribute('check','false')
$node = $xml.SelectSingleNode('component')
$node.AppendChild($child)
  

Комментарии:

1. Интересно, что насчет «SelectSingleNode», который пробел все еще вызывает сбой.

2. То же самое относится component и к имени элемента, поэтому удалите из него «name». Извините за это, я не запустил код, чтобы определить проблему, и пропустил ее.

3. 1. Ошибка нулевого значения. и как сохранить изменение xml в конце?

4. $node = $xml.SelectSingleNode(‘component’) возвращает ошибку с нулевым значением. и как сохранить изменение xml в конце?

5. Звук, возможно, работает, но как сохранить его в xml t, чтобы подтвердить, работает ли его $node = $xml.SelectSingleNode(‘//component’)

Ответ №2:

Вот ваше преобразование идентификатора XSLT.

Это работает очень простым и мощным способом. Он скопирует входной XML как есть. Но когда он доберется до <enabledExternalComponentSources> элемента, он добавит новый элемент

<option name="CHECK_NEEDED" value="false" /> в нужное место. Это именно то, что вам нужно.

 <?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

   <!-- IdentityTransform -->
   <xsl:template match="/ | @* | node()">
         <xsl:copy>
               <xsl:apply-templates select="@* | node()" />
         </xsl:copy>
   </xsl:template>
   
   <xsl:template match="enabledExternalComponentSources">
        <option name="CHECK_NEEDED" value="false" />
         <xsl:copy>
               <xsl:apply-templates select="@* | node()" />
         </xsl:copy>
   </xsl:template>   

</xsl:stylesheet>
  

Чтобы посмотреть, что он делает: скрипка XSLT

Простой сценарий Powershell для XSLT

Комментарии:

1. Как вы применяете XSLT с Powershell? Итак, если я правильно понимаю, это похоже на установщик Windows MST ?!

Ответ №3:

Это будет работать:

 $fileName = “C:sovgardeupdates.xml”;
$xml = [System.Xml.XmlDocument](Get-Content $fileName);

$child = $xml.CreateElement('option')
$child.SetAttribute('name', 'CHECK_NEEDED')
$child.SetAttribute('value','false')
$node = $xml.SelectSingleNode('//component')
$node.AppendChild($child)
$node
$xml.Save($fileName)
  

Теперь я пытаюсь удалить атрибут check_needed, и он не работает

    $fileName = “C:sovgardeupdates.xml”;
$xml = [System.Xml.XmlDocument](Get-Content $fileName);

$child = $xml.CreateElement('option')
$child.SetAttribute('name', 'CHECK_NEEDED')
$child.SetAttribute('value','false')
If ($xml.application.component.option.name -icontains "CHECK_NEEDED") {
    
    $node = $xml.SelectSingleNode('//component')
    $node.RemoveAttribute('CHECK_NEEDED') 
    $xml.Save($fileName)   
    
}
  

Обнаружение работает правильно, но после сохранения значение все еще существует.