0

I am not sure how to use regex to do the following: within the edge tags (), check if type="highway.secondary", and if yes, replace all values of speed to 40.

<edge id="-100396051#2" type="highway.unclassified">
        <lane id="-100396051#2_0" index="0"  speed="13.89">
            <param key="origId" value="100396051"/>
        </lane>
    </edge>
    <edge id="-101784374#0" type="highway.secondary">
        <lane id="-101784374#0_0" index="0"  speed="27.78" length="17.22" >
            <param key="origId" value="101784374"/>
        </lane>
        <lane id="-101784374#0_1" index="1" speed="29.98" length="17.22" >
            <param key="origId" value="101784374"/>
        </lane>
    </edge>

So far I got this: (?<=type="highway\.secondary")(speed)(?=edge), but that doesn't find speed... Thanks!

3
  • 7
    Use an XML parser instead Commented Apr 2, 2019 at 6:38
  • 1
    My answer should solve your problem! It is based on XSLT technologies to parse the input XML and generate the desired XML output Commented Apr 2, 2019 at 9:28
  • 1
    Some call it summoning the daemon, others refer to it as the Call for Cthulhu and few just turned mad and met the Pony. In short, never parse XML or HTML with a regex! Did you try an XML parser such as xmlstarlet, xmllint or xsltproc? Commented Apr 4, 2019 at 8:59

1 Answer 1

2

INPUT: edges.xml

<edges>
  <edge id="-100396051#2" type="highway.unclassified">
        <lane id="-100396051#2_0" index="0"  speed="13.89">
            <param key="origId" value="100396051"/>
        </lane>
    </edge>
    <edge id="-101784374#0" type="highway.secondary">
        <lane id="-101784374#0_0" index="0"  speed="27.78" length="17.22" >
            <param key="origId" value="101784374"/>
        </lane>
        <lane id="-101784374#0_1" index="1" speed="29.98" length="17.22" >
            <param key="origId" value="101784374"/>
        </lane>
    </edge>
</edges>

STYLESHEET: change_speed.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" encoding="utf-8" indent="yes"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:template match="@speed[../parent::edge and ../../@type='highway.secondary']">
    <xsl:attribute name="speed">
      <xsl:value-of select="'40'"/>
    </xsl:attribute>
</xsl:template>


</xsl:stylesheet>

OUTPUT:

$ xsltproc change_speed.xsl edges.xml 
<?xml version="1.0" encoding="utf-8"?>
<edges>
  <edge id="-100396051#2" type="highway.unclassified">
        <lane id="-100396051#2_0" index="0" speed="13.89">
            <param key="origId" value="100396051"/>
        </lane>
    </edge>
    <edge id="-101784374#0" type="highway.secondary">
        <lane id="-101784374#0_0" index="0" speed="40" length="17.22">
            <param key="origId" value="101784374"/>
        </lane>
        <lane id="-101784374#0_1" index="1" speed="40" length="17.22">
            <param key="origId" value="101784374"/>
        </lane>
    </edge>
</edges>

Explanations:

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

Will copy all the nodes and attributes recursively

<xsl:template match="@speed[../parent::edge and ../../@type='highway.secondary']">
    <xsl:attribute name="speed">
      <xsl:value-of select="'40'"/>
    </xsl:attribute>
</xsl:template>

When you reach an attribute named speed for which the parent node is named edge and has an attribute type whose value is at highway.secondary, change the value of this attribute to 40.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.