Search code examples
xmlwindowspowershellcmdxmlstarlet

Xmlstarlet command from terminal to Windows Powershell


On my terminal (linux/mac) I use this:

xmlstarlet ed -N ns=http://www.w3.org/2006/04/ttaf1 -d //ns:div[not(contains(@xml:lang,'Italian'))] "C:\Users\1H144708H\Downloads\a.mul.ttml" > "C:\Users\1H144708H\Downloads\a.mul.ttml.conv"

On windows (powershell) I really don't know how to fix this command. I know that I need to use $ instead of @ (because the powershell said to use $ instead of @), but there is something wrong with contains:

./xml.exe ed -N ns=http://www.w3.org/2006/04/ttaf1 -d //ns:div[not(contains($xml:lang,'Italian'))] "C:\Users\1H144708H\Downloads\a.mul.ttml" > "C:\Users\1H144708H\Downloads\a.mul.ttml.conv"

I even tried this:

./xml.exe ed -N ns=http://www.w3.org/2006/04/ttaf1 -d //ns:div[not($xml:lang -contains'Italian')] "C:\Users\1H144708H\Downloads\a.mul.ttml" > "C:\Users\1H144708H\Downloads\a.mul.ttml.conv"

But I get "failed to load external entity "False""


Solution

  • //ns:div[not(contains(@xml:lang,'Italian'))] is an XPath expression which contains some characters that are special to various shells, therefore you should protect it with quotes. Using double quotes works in bash, Powershell, and cmd.exe:

    xmlstarlet ed -N ns=http://www.w3.org/2006/04/ttaf1 -d "//ns:div[not(contains(@xml:lang,'Italian'))]" "C:\Users\1H144708H\Downloads\a.mul.ttml" > "C:\Users\1H144708H\Downloads\a.mul.ttml.conv"
    

    When using bash or Powershell it may be preferable to use single quotes; for those shells this is needed to protect against expansion of $ (although use of this in XPath is fairly advanced):

    xmlstarlet ed -N ns=http://www.w3.org/2006/04/ttaf1 -d '//ns:div[not(contains(@xml:lang,"Italian"))]' "C:\Users\1H144708H\Downloads\a.mul.ttml" > "C:\Users\1H144708H\Downloads\a.mul.ttml.conv"
    

    Note that the inner quotes need to swapped as well.