Brian Hershey
Brian Hershey

Reputation: 43

Loop through SVG attributes with PHP

Using PHP, I need to read in a csv file of id's...

0123,0456,0789

... then load a SVG XML graphics file and change the color attribute of those specific id's.

Each polygon in the SVG file has records like below. I need to change the fill: values in every matching record from #d0d0d0 to #FF0000. Outer loop will be the ids of course, inner will be each record of the SVG file.

style="font-size:12px;fill:#d0d0d0;fill-rule:nonzero;stroke:#000000;stroke-opacity:1;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-linecap:butt;marker-start:none;stroke-linejoin:bevel" d="M 131.85275,310.64335 L 131.85275,311.08435" id="0123"

For my hobbyist level of programming skill, a general PHP structure of the loops needed plus tips how to access specific attributes of style would be very helpful!

Thanks! Brian

Upvotes: 0

Views: 1782

Answers (2)

Thomas W
Thomas W

Reputation: 15381

I'd recommend a different approach: Use CSS for changing the color. No looping over SVG elements required there. To be able to do this, you should clean up the SVG file a little, which also will make it more compact.

As I understand it, all your to-be-colored elements have the same style attribute with content

font-size:12px;fill:#d0d0d0;fill-rule:nonzero;stroke:#000000;stroke-opacity:1;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none;stroke-linecap:butt;marker-start:none;stroke-linejoin:bevel

Delete those attributes, replace them with a sensible class attribute. Let's say those paths are countries on a map, then lets give them an attribute class="country". Then style all of those using one CSS rule, like:

.country {
  fill:  #d0d0d0;
  fill-rule:nonzero;
  stroke:#000000;
  stroke-opacity:1;
  stroke-width:0.1;
  stroke-miterlimit:4;
  stroke-dasharray:none;
  stroke-linecap:butt;
  marker-start:none;
  stroke-linejoin:bevel;
}

I left away the font-size property as this is irrelevant for a <path> element. (Probably you can simplify this further because a lot of properties repeat the default values, and unless you change those properties in a parent element of your paths, fill-rule, stroke-opacity, stroke-miterlimit, stroke-dasharray, stroke-linecap and marker-start are redundant, but don't hurt anyone.)

There is one more problem: If the IDs in your file look indeed like 0123, 0456 or 0789, those are invalid because they need to follow the rules for XML names, which must not start with a number. You should expect problems when trying to style those elements using their IDs or when trying to use getElementById() on them. So, you might want to change them to something like id0123, id0456 and id0789

Now, you can dynamically add some CSS from your CSV data.

0123,0456,0789

would become

#id0123,#id0456,#id0789 {fill:#FF0000}

and you're done. The CSS can be added to a <style> element of your SVG file, or you create a separate CSS file and reference this from the SVG. This way, you don't have to do any changes to the SVG when dynamically changing the colors. If you use the SVG data inline in HTML, you can also add this to a <style> element in your HTML page or a CSS file that's referenced by the HTML.

Upvotes: 0

NoBugs
NoBugs

Reputation: 9492

The DOMDocument object has getelementbyid, getAttribute and setAttribute, which should let you change the xml.

This example looks similar to what you're wanting, once you get the styles you can explode with ';' to get the array of styles, then join with the new styles.

Upvotes: 0

Related Questions