2015-05-27 3 views
0

У меня есть куча XML-файлов, я хочу обнаружить и удалить в них пустые теги. как:Как обнаружить и удалить пустые теги XML?

<My></My> 
<Your/> 

<sometags> 
    <his> 
    </his> 
    <hasContent>sdfaf</hasContent> 
</sometags> 

Они все виды пустых тегов (My, Your, his) Я желаю, чтобы удалить. Поддерживает ли PowerShell такое обнаружение пустых тегов, независимо от того, насколько глубоко они встроены в другие теги?

ответ

6
function Format-XML 
{ 
    param (
     [parameter(Mandatory = $true)][xml] $xml, 
     [parameter(Mandatory = $false)][int] $indent = 4 
    ) 

    try 
    { 
     $Error.Clear() 

     $StringWriter = New-Object System.IO.StringWriter 
     $XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter 
     $xmlWriter.Formatting = "indented" 
     $xmlWriter.Indentation = $indent 
     $xml.WriteContentTo($XmlWriter) 
     $XmlWriter.Flush() 
     $StringWriter.Flush() 

     return $StringWriter.ToString() 
    } 

    catch 
    { 
     Write-Host "$($MyInvocation.InvocationName): $_"; return $null 
    } 
} 


$xml = [xml] @" 
<document> 
    <My></My> 
    <Your/> 
    <sometags> 
     <his> 
     </his> 
     <hasContent>sdfaf</hasContent> 
    </sometags> 
</document> 
"@ 

# The "magic" part is in this XPath expression 

$nodes = $xml.SelectNodes("//*[count(@*) = 0 and count(child::*) = 0 and not(string-length(text())) > 0]") 

$nodes | %{ 
    $_.ParentNode.RemoveChild($_) 
} 

Format-Xml $xml 
+2

Спасибо, но не могли бы вы объяснить, какие 3 части волшебной строки XPath? –

+0

В качестве примечания, Джеффри Снавер обновил [статью] (http://blogs.msdn.com/b/powershell/archive/2008/01/18/format-xml.aspx), где он опубликовал эту функцию форматирования с даже более быстрое предложение Ли Холмса: '$ xml.Save ([Console] :: Out)'. –

+0

Видит $ xml.Save не существует для [XML], я просто попытался: $ XML = @ " sdfaf " @ $ x = [xml] $ xml $ x.Save ([Console] :: Out) documentMyMyYo ur/sometagshishishasContentsdfafhasContentsometagsdocument –

1

Я не владеет в PowerShell, так что только немного дополнение к хорошему ответу @DavidBrabant «s, в частности, в XPATH части. XPath для обнаружения пустых элементов может быть немного проще:

//*[not(@*) and not(*) and normalize-space()] 

Предикатов (все в пределах []), в порядке, проверяет, является ли текущий элемент не имеет атрибут, не имеет дочерний элемент, и не имеют пустой текстовый узел.

0

Вы должны искать решение, которое использует System.Xml.XmlDocument. Но его также можно использовать с регулярным выражением:

$xml = @" 
<document> 
    <My></My> 
    <Your/> 
    <sometags> 
     <his> 
     </his> 
     <hasContent>sdfaf</hasContent> 
    </sometags> 
</document> 
"@ 

$xml -replace '(?:<(\w*)>\s*<\/\1>)|<(\w*)\/>', '' 
Смежные вопросы