Do you see what the problem is? For those of you playing at home, here's a hint: how would you write an XPath expression to obtain the "equivalents" of a given image file?<plist version="1.0">
<dict>
<key>AdiumSetVersion</key>
<integer>1</integer>
<key>Emoticons</key>
<dict>
<key>amazing.png</key>
<dict>
<key>Equivalents</key>
<array>
<string>=-o</string>
<string>=-O</string>
<string>:-o</string>
<string>:-O</string>
</array>
<key>Name</key>
<string>Surprised</string>
</dict>
<key>anger.png</key>
<dict>
<key>Equivalents</key>
<array>
<string>>:o</string>
<string>:-@</string>
<string>:@</string>
<string>X(</string>
</array>
<key>Name</key>
<string>Angry</string>
</dict>
<key>bad_egg.png</key>
<dict>
<key>Equivalents</key>
<array>
<string>>-[</string>
<string>>-(</string>
</array>
<key>Name</key>
<string>Nervous</string>
</dict>
(...snip...)
</dict>
</dict>
</plist>
Yes, it's not impossible to grab a value for a given key, but did they have to make it so hard when XML can express the same idea in a much easier format? Or, rather, did they have to be so lazy when writing the code that serializes these property lists to/from XML?
In any case, if you ever have the need to process an XML file created by an Apple program, the following stylesheet will (likely) help restore your sanity. Simply pre-process the XML with my stylesheet and then your XML code or stylesheet will be much easier to write (and read!):
For an example, let's take another look at the sample XML I showed earlier and compare that with the XML sexiness that is generated by applying my stylesheet against it (some spacing was added to the "after" version to better illustrate how they compare to each other):<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="utf-8" indent="yes" />
<xsl:template match="* | @* | node()">
<xsl:copy>
<!-- if the previous sibling is a 'key' element -->
<xsl:if test="name(preceding-sibling::*[position()=1]) = 'key'">
<xsl:attribute name="key">
<xsl:value-of select="preceding-sibling::key[position()=1]/text()" />
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="* | @* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="key" />
</xsl:stylesheet>
Before | After |
---|---|
<plist version="1.0"> | <plist version="1.0"> |
...isn't that a sight for sore eyes? You're welcome.