Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

powershell - Comment XML section (having prefixes in the nodes) and un-comment other

This is my sample xml data. Please ignore if there is any syntax error or some missing xml features. The task is to comment the above section and un-comment the below section.

<?xml version="1.0" encoding="UTF-8"?>
<providersbeans xmlns="http://www.springframework.org/schema/providers"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:dns="http://www.springframework.org/schema/dns"
  xsi:schemaLocation="http://www.springframework.org/schema/dns/spring-dns.xsd">

<!-- COMMENT THIS SECTION -->

<dns:auth-head alias="authHead">
    <dns:user-generator>    
        <dns:user-data>

            <!-- USER AA -->
            <dns:user name="AA"
                password="AAAAAAAAAAAAAAAA" role="ROLE_AA" />

            <!-- USER BB -->
            <dns:user name="BB"
                password="XXXXXXXXXXXXXXX" role="ROLE_BB" />

        </dns:user-data>            
    </dns:user-generator>
</dns:auth-head>


<!-- UNCOMMENT THIS SECTION-->
<!-- 
<bean id="authHead" class="org.xx.providers"> 
    <property name="providers">
        <list>
            <ref bean="AuthProvider"/>
        </list>
    </property>
</bean>
-->
</providersbeans>

I tried some of the solutions but couldn't get success since it has a prefix in it. One of the code that I adapted for just commenting is this:

$getxmlpath='C:Powershellsecurityfile.xml'
$xml=[xml](Get-Content $getxmlpath)
$xml.SelectNodes("//auth-head") | ForEach-Object # used with prefix as well, but didnt work
{ 
  $var= $_;
  $mycomment = $xml.CreateComment($var.OuterXml);
  $var.ParentNode.ReplaceChild($mycomment , $var);
}
$xml.Save($getxmlpath);
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Something like this might work:

[xml]$xml = Get-Content 'C:Powershellsecurityfile.xml'

# create namespace manager
$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$nsm.AddNamespace('dns', $xml.DocumentElement.dns)

# remove nested comments from <auth-head> node(s)
($xml.SelectNodes('//dns:auth-head//comment()', $nsm)) | % {
  [void]$_.ParentNode.RemoveChild($_)
}
# comment-out node(s)
($xml.SelectNodes('//dns:auth-head', $nsm)) | % {
  $comment = $xml.CreateComment($_.OuterXml)
  [void]$_.ParentNode.ReplaceChild($comment, $_)
}

# uncomment <bean> node(s)
($xml.SelectNodes('//comment()')) | ? {
  $_.InnerText -like '*<bean*'
} | % {
  $newxml = [xml]$_.InnerText
  $node = $xml.ImportNode($newxml.DocumentElement, $true)
  $node.SetAttribute('xmlns', $xml.DocumentElement.NamespaceURI)
  [void]$_.ParentNode.ReplaceChild($node, $_)
}

I was unable to find a way to re-insert the <bean> node without it getting an explict (empty) namespace attribute (xmlns=""), so I set that attribute to the default namespace of the XML document.

Note that you must remove (or otherwise modify) the nested comments from the node you wish to comment out. Otherwise the closing --> from the first nested comment would prematurely terminate the comment node, leaving you with an invalid XML structure:

<!--dns:auth-head alias="authHead">
    <dns:user-generator>    
        <dns:user-data>

            <!-- USER AA -->   # XML comment ends here!
            <dns:user name="AA"
                password="AAAAAAAAAAAAAAAA" role="ROLE_AA" />

            <!-- USER BB -->
            <dns:user name="BB"
                password="XXXXXXXXXXXXXXX" role="ROLE_BB" />

        </dns:user-data>       # tags from here on are invalid, because
    </dns:user-generator>      # they're missing their respective opening tag
</dns:auth-head-->

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...