20050419

A Window Into My Work Day

WARNING: Highly technical stuff ahead. Do not proceed without a pocket protector.

Here's a good puzzle for you. How do you use a literal quotation mark in quoted XML text in a string wrapped by the same kind of quotation mark in an XPath query?

If you say:
comments[text()="There's a 48" door."]

The quotation mark after the 48 ends the text quotation, and the final part of the string (" door.",) is unexpected, and causes a syntax error. Simple enough so far, right?

A literal quotation mark in an XPath string is NOT automatically escaped to it's character entity to indicate a literal quotation mark. Instead, it's naturally used as part of the XPath code, to break the XPath string.

Your first impulse might be to switch quotation mark types. I disdain the switching of quotation mark types. In my opinion, the double quotation mark should always be used to indicate a string quotation, and if it must be escaped, it should be escaped. Some people prefer to use the alternative single quotation mark, but as I'll demonstrate, that doesn't really get you anywhere. It generally just makes things more complicated. Consider our example.

To solve my problem, you might try changing the query to:
comments[text()='There's a 48" door.']

This was a great thought, because now the double quotation mark in the quoted text won't be used to terminate the XPath string, like it was before. Astute observers, however will instantly discover another problem. The single quotation mark, used in our example for an apostrophe, WILL terminate the string, which is now wrapped in single quotation marks, and we're back at square one.

Switching between wrapping a string in double and single quotation marks, doesn't solve the problem of how to indicating that a double or single quotation mark is to be taken as a literal part of the string, instead of as a string terminator.

No problem, I told myself. I'll just use the special XML character entities to escape the literal quotation marks. XML defines two character entities to indicate that a quotation mark is a literal part of the string instead of a string terminator. The entities are " for a double quote, and ' for a single quote.

So I fixed my query like this:
comments[text()="There's a 48" door."]

I thought that XPath string should now literally contain my quotation marks. But then I was really shocked. I don't know whether this is an error with my XPath implementation, or what, but now the real fun begins.

Naturally, XPath assumed I couldn't possibly be wanting to put a literal ampersand character in the string, and start an entity. What? How am I supposed to indicate an entity within an XPath string? XPath promptly converted the ampersands to the XML character entity for literal ampersands, &.

The query, of course, only matches strings that actually look like this:
There's a 48" door.

I wonder why it took me so long to realize this now obvious rule:

Ampersands, along with less than, and greater than symbols, ARE automatically converted to their literal character entities when used within XPath strings, because XPath queries themselves are XML strings.

Wow. Doesn't this present a blissfully fun, uniquely challenging puzzle? This is the kind of thing we programmers really like.

Two ideas immediately hit me to solve this problem. First, I figured, why not just double-escape the quotation marks by escaping the characters in the escape sequence?

Now my query starts out like this:
comments[text()="There's a 48" door."]

We're getting in deeper!

When the query is converted into an XML string, I assume it will come out like this:
comments[text()="There's a 48" door."]

When the XPath string is actually processed as part of the XPath, I assume the new ampersands will be converted back to real literal ampersands in the query itself:
comments[text()="There's a 48" door."]

And then the ampersands in the string will indicate literal ampersands to the query processor, like this:
comments[text()="There's a 48" door."]

And the query processor will process the string as an XML string when it's querying the XML, so the entities will be un-escaped again, and match text like this:
There's a 48" door.

Which is what I wanted all along. But, I was wrong again. The selectNodes and selectSingleNode DOM methods don't use XML strings, so it still doesn't work.

Another idea I've had to far is that maybe one of the processing layers will skip numeric character code entities, instead of treating them the same as the named character entities, and so I'll be able to indicate literal quotation marks using the character code numbers in numeric XML entities. How would that work?

How about if I catted the entity together, like this:
concat("&nb","sp;")

Would that help? What would that do?

Otherwise, the thing left that I can think of to do is to put the XPath string in it's own node or param/variable, and refer to the variable/param/node from the XPath. But how do I use a variable with the selectSingleNode method?

I found out that somebody else had the same problem.

Just a little thinking out-loud, and a little window into the world I work in all day.

Oh, uh- did I mention what Blogger does when you try to put all these escape characters and escape codes for escape characters, and everything, in your blog? Let's just say it adds even more fun. Maybe I'll post another message later about the Hebrew language I'm learning- that shouldn't be too much more complicated to understand.

20050418

Out The Window By My Office

On Wheels

Watch out when you're on or near the road-

I've been driving!

I've been practicing in traffic more and more, and had all kinds of good experience- driving at night, switching lanes, curves, bumps, other crazy drivers screaming their heads off at me, water (a lot of water,) a little wind, gravel, pedestrians, and a little black squirel. I actually had the discipline to ignore him and not swerve or anything- Thank the Lord the cute little guy happened to get away. On the other hand, I saw a few bumper stickers on vehicles I wanted to hit... but resisted.

I was worried because my learners permit was set to expire on a certain date. But then when I got it out that day, thinking, Oh Brother, now it's expired, I was surprised that it had more time left on it.

I had forgotten that when the DMV had my name spelled wrong, and I got a new card to correct it, they gave me more time. Praise the Lord, that was His goodness. By the way, the reason I capitalize the two A's in the middle of isAAc is so people will be able to spell it correctly.

I've been praying for safety when I drive, and so far I haven't had an accident- even going 45mph (where it was legal, of course.) I might have to replace the tires on the left side of the car though- hitting all those curbs is rather tough on them!

20050413

20050407

A Standard Against The Enemy

Isaiah 59:19
So shall they fear the name of the LORD from the west, and his glory from the rising of the sun. When the enemy shall come in like a flood, the Spirit of the LORD shall lift up a standard against him.
The enemy has been attacking like an overwhelming flood. A little while ago, I remembered this promise, praise the Lord. Yesterday I started praying that the Lord would keep this promise and lift up a standard against the enemy. Before I fell asleep last night, I was praying, Lift up a standard against the enemy, Lift up a standard against the enemy. I was surprised and delighted to find this very verse in my Bible reading for today, because I had no idea where this verse was in the Bible. Yesterday I said Amen when I was praying with a friend, who prayed, "show us a token for good." God has shown me His Love, once again! Despite my sins and slothfulness and weakness and fears and confusion, He's shown me He's real, and true, and living, and active! He's worth my trust, and He delights to hear my voice and answer my prayers! Everything the Lord does is good. Let the Lord be magnified!

20050405

Dwelling in The Holy Place

Isaiah 57:13
When thou criest, let thy companies deliver thee; but the wind shall carry them all away; vanity shall take [them]: but he that putteth his trust in me shall possess the land, and shall inherit my holy mountain;
The Lord was angry with us because of our covetousness and sinful hearts. He smote us and hid His face from us. But He won't let our spirits and souls which He's made fail before Him. Put your trust in the Lord, with a humble and contrite heart. Regret and be sorry for your sins. He will heal us and give us peace, but there's no peace to the wicked. Isaiah 57:15
For thus saith the high and lofty One that inhabiteth eternity, whose name [is] Holy; I dwell in the high and holy [place], with him also [that is] of a contrite and humble spirit, to revive the spirit of the humble, and to revive the heart of the contrite ones.

20050401

Forsake Unrighteous Thoughts

Isaiah 55:7
Let the wicked forsake his way, and the unrighteous man his thoughts: and let him return unto the LORD, and he will have mercy upon him; and to our God, for he will abundantly pardon.
Would you like goodness and delight for your soul, life for your soul, His everlasting covenant, and sure mercies? Would you like to be glorified? Would you like to find the Lord? Diligently listen to the Lord, call on Him, and forsake your wicked way and unrighteous thoughts. The Lord will abundantly pardon you! Isaiah 55:12
For ye shall go out with joy, and be led forth with peace: the mountains and the hills shall break forth before you into singing, and all the trees of the field shall clap [their] hands.
Bookmark and Share