Home > OS >  Select Single XML Node to check Node is already added using PowerShell
Select Single XML Node to check Node is already added using PowerShell

Time:12-28

Firstly, I was able to add Filter to the xml file via PowerShell script as below.

$file = Resolve-Path 'backup.xml'

$output = [xml](Get-Content $file)

$expiresFilterSingleNodeValue = $output.SelectSingleNode("//filter/filter-name[. = 'ExpiresFilter']")

if($expiresFilterSingleNodeValue -ne $null ) {
    return
}

$mainNode = $output.DocumentElement

$newNode = [xml]@"
<filter>
    <filter-name>ExpiresFilter</filter-name>
    <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
    <init-param>
       <param-name>ExpiresByType image</param-name>
       <param-value>access plus 1 day</param-value>
    </init-param>
    <init-param>
       <param-name>ExpiresByType text/css</param-name>
       <param-value>access plus 1 day</param-value>
    </init-param>
    <init-param>
       <param-name>ExpiresByType application/javascript</param-name>
       <param-value>access plus 1 day</param-value>
    </init-param>
    <init-param>
       <param-name>ExpiresByType font</param-name>
       <param-value>access plus 1 day</param-value>
    </init-param>
</filter>
"@

$newNode = $output.ImportNode($newNode.DocumentElement, $true)
$mainNode.appendChild($newNode) | out-null

$newNode2 = [xml]@"
<filter-mapping>
    <filter-name>ExpiresFilter</filter-name>
    <url-pattern>/baseurl/single/node</url-pattern>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>
"@

$newNode2 = $output.ImportNode($newNode2.DocumentElement, $true)
$mainNode.appendChild($newNode2) | out-null

$output.Save($file)

Additionally, latest state of file structure as below:

<web-app> 
    <filter xmlns="">
    <filter-name>ExpiresFilter</filter-name>
    <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
    <init-param>
      <param-name>ExpiresByType image</param-name>
      <param-value>access plus 1 day</param-value>
    </init-param>
    <init-param>
      <param-name>ExpiresByType text/css</param-name>
      <param-value>access plus 1 day</param-value>
    </init-param>
    <init-param>
      <param-name>ExpiresByType application/javascript</param-name>
      <param-value>access plus 1 day</param-value>
    </init-param>
    <init-param>
      <param-name>ExpiresByType font</param-name>
      <param-value>access plus 1 day</param-value>
    </init-param>
  </filter>
  <filter-mapping xmlns="">
    <filter-name>ExpiresFilter</filter-name>
    <url-pattern>/baseurl/single/node</url-pattern>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
</web-app>

However script is going to be triggered more than one time. By that reason, Filter is also going to be added to the file and issue is going to be occurred.

In conclusion, as one can see from script, I've added a code block to check the Filter is exist or not in the file. But it is not working properly. In other words, I do not want add Filter into the file again even if it is added.

$expiresFilterSingleNodeValue = $output.SelectSingleNode("//filter/filter-name[. = 'ExpiresFilter']")

if($expiresFilterSingleNodeValue -ne $null ) {
    return
}

Could you please assist me for that?

CodePudding user response:

Your target <filter> is not a child of another <filter> as your xpath expressions assumes; it's a child of <filter-mapping>.

So try simplifying your xpath expression to

//filter-name[. = 'ExpiresFilter']

or

//web-app//filter-name[. = 'ExpiresFilter']

and see if it works.

  • Related