Search code examples
xmlcommand-linekmlxmlstarlet

Select XML element based on the value of a tag


I need to select all <Style> blocks from a KML that contain the color ccff00ff. Something like:

<Style id="inline">
    <LineStyle>
        <color>ccff00ff</color>
        <width>5</width>
    </LineStyle>
</Style>

I have been beating my head against the wall for hours, and this is the closest I could get based on this discussion:

xmlstarlet sel -N 'ns=http://www.opengis.net/kml/2.2' -t -c '//ns:Style[.//ns:color[contains(text(), 'ccff00ff')]]' myplaces.kml

Unfortunately, if I change ccff00ff to whatever I want, it still matches, so I can assume it doesn't work at all!


Solution

  • '//ns:Style[.//ns:color[contains(text(), 'ccff00ff')]]'
    

    Quotes don't nest; use double quotes inside the single ones:

    '//ns:Style[.//ns:color[contains(text(), "ccff00ff")]]'
    

    The example you linked had the quotes the other way around, because cmd.exe doesn't recognize single quotes as quoting characters. Since bash does recognize double quotes as quoting characters too you could do it that way, but they are "soft quotes" so you could run into some trouble with that. As far as XPath is concerned, both quote types are completely identical.