jhy/jsoup — pull request #480 by tipabu (2014-10-21 05:37:57+00:00)
Title: Allow case-sensitive retrieval of element and attribute names.

Addresses #29, #272, #328, #344, #407, and #466.

`Element`s and `Attribute`s each have new getters (`tagName` and `getKey`, respectively) that take a boolean (`preserveCase`) as an argument. If true, the original string used to construct the object will be returned; otherwise, the lower-cased version will be returned, as before. Additionally, a new `preserveCase` option has been added to `OutputSettings`: this is referenced when rendering content using `outerHtml()` and the like. When rendering, the closing tags for elements will always match the casing of the opening tag.

There are two implementation details worth noting, however: First, `Tag`s, `Element`s, and `Attribute`s now retain both the original tag/attribute name and a lower-case version of it. This has some benefits at the cost of an increased memory footprint:

1. Existing code that makes direct reference to `tagName` and `key`
didn't need to change.
2. Case-insensitive comparison (for end-tag matching and element
selection, for example) is somewhat faster than repeatedly calling
`.equalsIgnoreCase()` on the same string.

Second, HTML tags that are not already all-lower-case will be treated like unrecognized XML tags, with new `Tag` objects created for each. Like other unknown `Tag`s, these will `.equals()` but not `==` other `Tag`s with the same (case insensitive) name. Their other properties (`canContainBlock`, `canContainInline`, etc.) will be copied from the registered version. This has two downsides:

1. The memory footprint will again increase, though it should be no
worse than parsing a comparably-sized XML document.
2. Existing code that relies on strict equality of HTML tags with the
same name will break. This is unavoidable if we wish to preserve,
for example, both `

` and `

` in a document, though we may still
want to make `Tag.valueOf("P") == Tag.valueOf("P")`. It should be
noted, however, that `Element` doesn't offer a comparable guarantee.