Search code examples
regexnotepad++kmlgoogle-earth

KML Inserting a Specific Tag between Two Other Tags Based on a Condition


TLDR - Insert the Style tag and its contents (see code blocks) between the name and description tag only if the description mentions the phrase "the office" in order to change the current Google Earth placemark from the default yellow one to a custom one...

Hi guys, I’m having a bit of trouble figuring this one out… Using Notepadd++ I am editing a Google Earth kml file where I have many placemarks that follow this XML pattern:

<Placemark>
      <name>Jim</name>
      <description>Jim goes to the office every day</description>
      <TimeSpan>
        <begin>2016-06-20T12:00:00Z</begin>
        <end>2016-06-25T12:00:00Z</end>
      </TimeSpan>
      <Point>
        <coordinates>123412341234,123412341234,1</coordinates>
      </Point>
        </Placemark>

I would like to find every instance of the phrase “the office”. If that text is found, the code below is inserted between name and description in a fashion that would be readable by Google earth.

<Style id="customstyle">
        <IconStyle>
            <color>a1ff00ff</color>
            <scale>1.5</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href>
            </Icon>
        </IconStyle>
            </Style>

Doing this would change the placemark from the default one to a custom one.

All of the tutorials I have found thus far, have been instructions on how to add words or phrases to the beginning or end of a line using Notepad++ regex, or the instructions show how to insert text on the next line using \n. However, I think my situation is unique in that based on a certain criteria I want to insert my text above the line. (more specifically insert my text between the name and description tags)

The end result would look something like this (notice how the text I wanted to add is now in between the name tag and the description tag)

<Placemark>
      <name>Jim</name>
      <Style id="customstyle">
        <IconStyle>
            <color>a1ff00ff</color>
            <scale>1.5</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href>
            </Icon>
        </IconStyle>
        </Style>
      <description>Jim goes to the office every day</description>
      <TimeSpan>
        <begin>2016-06-15T12:00:00Z</begin>
        <end>2016-06-20T12:00:00Z</end>
      </TimeSpan>
      <Point>
        <coordinates>2135125,1234523451,12341234</coordinates>
      </Point>
    </Placemark>

Now all placemarks that followed that pattern would have a different type of placemark than the default one (and i would no longer have a headache).

Thanks in advance all.


Solution

  • Well, the regex doesn't really need to match something before the line.
    It just needs to put something with lines before your match.
    So it's still a fairly simple thing to do.

    So using Notepad++

    Find What : (\s+)(<description>)(?=.*?the office.*?<\/description>)

    Replace with : $1<Style id="customstyle">$1\t<IconStyle>$1\t\t<color>a1ff00ff</color>$1\t\t<scale>1.5</scale>$1\t\t<Icon>$1\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href>$1\t\t</Icon>$1\t</IconStyle>$1</Style>$1$2

    Search mode : Regular Expression

    Note that the whitespaces before the description tag are put in capture group 1.
    That's a trick make an insert with the same indentation as the tag.

    But you could also just put in tags without whitespaces.

    Find What : (<description>)(?=.*?the office.*?<\/description>)

    Replace with : <Style id="customstyle"><IconStyle><color>a1ff00ff</color><scale>1.5</scale><Icon><href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href></Icon></IconStyle></Style>$1

    And then use a plugin like "XML Tools" to "Pretty Print" your XML.