注释XML部分(节点中有前缀)并取消注释其他部分。

3

这是我的示例XML数据,请忽略任何语法错误或一些缺失的XML功能。 任务是对上面的部分进行注释,并取消对下面部分的注释。

<?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>

我尝试了一些解决方案,但由于其中有一个前缀,无法成功。其中一个我仅作注释的代码是这样的:

$getxmlpath='C:\Powershell\securityfile.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);
1个回答

1
像这样的东西可能会起作用:

[xml]$xml = Get-Content 'C:\Powershell\securityfile.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, $_)
}

我无法找到重新插入<bean>节点的方法,而不使其获得显式(空)命名空间属性(xmlns=""),因此我将该属性设置为XML文档的默认命名空间。
请注意,您必须删除(或以其他方式修改)要注释的节点中的嵌套注释。否则,第一个嵌套注释的关闭标记-->会过早地终止注释节点,使您得到一个无效的XML结构:
<!--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-->

谢谢,只需要保存文件。不过,我没有想到首先要清除所有注释,因为在xml中保留注释时,它根本不起作用,至少对我来说是这样。再次感谢您的及时帮助。 - Kriti
@Kriti:嵌套的注释会提前终止被注释掉的节点,导致XML无效。我在我的答案中添加了一条备注。 - Ansgar Wiechers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接