001: package net.sf.saxon.om;
002:
003: /**
004: * ProcInstParser is used to parse pseudo-attributes within Processing Instructions
005: * @author Michael H. Kay
006: * @version 10 July 2000
007: */
008:
009: public class ProcInstParser {
010:
011: /**
012: * Class is never instantiated
013: */
014:
015: private ProcInstParser() {
016: }
017:
018: /**
019: * Get a pseudo-attribute. This is useful only if the processing instruction data part
020: * uses pseudo-attribute syntax, which it does not have to. This syntax is as described
021: * in the W3C Recommendation "Associating Style Sheets with XML Documents".
022: * @return the value of the pseudo-attribute if present, or null if not
023: */
024:
025: public static String getPseudoAttribute(String content, String name) {
026:
027: int pos = 0;
028: while (pos <= content.length() - 4) { // minimum length of x=""
029: int nextQuote = -1;
030: for (int q = pos; q < content.length(); q++) {
031: if (content.charAt(q) == '"'
032: || content.charAt(q) == '\'') {
033: nextQuote = q;
034: break;
035: }
036: }
037: if (nextQuote < 0)
038: return null;
039:
040: int closingQuote = content.indexOf(content
041: .charAt(nextQuote), nextQuote + 1);
042: if (closingQuote < 0)
043: return null;
044: int nextName = content.indexOf(name, pos);
045: if (nextName < 0)
046: return null;
047: if (nextName < nextQuote) {
048: // check only spaces and equal signs between the name and the quote
049: boolean found = true;
050: for (int s = nextName + name.length(); s < nextQuote; s++) {
051: char c = content.charAt(s);
052: if (!Character.isWhitespace(c) && c != '=') {
053: found = false;
054: break;
055: }
056: }
057: if (found) {
058: String val = content.substring(nextQuote + 1,
059: closingQuote);
060: return unescape(val);
061: }
062: }
063: pos = closingQuote + 1;
064: }
065: return null;
066: }
067:
068: /**
069: * Interpret character references and built-in entity references
070: */
071:
072: private static String unescape(String value) {
073: if (value.indexOf('&') < 0)
074: return value;
075: FastStringBuffer sb = new FastStringBuffer(value.length());
076: for (int i = 0; i < value.length(); i++) {
077: char c = value.charAt(i);
078: if (c == '&') {
079: if (i + 2 < value.length()
080: && value.charAt(i + 1) == '#') {
081: if (value.charAt(i + 2) == 'x') {
082: int x = i + 3;
083: int charval = 0;
084: while (x < value.length()
085: && value.charAt(x) != ';') {
086: int digit = "0123456789abcdef"
087: .indexOf(value.charAt(x));
088: if (digit < 0) {
089: digit = "0123456789ABCDEF"
090: .indexOf(value.charAt(x));
091: }
092: if (digit < 0) {
093: return null;
094: }
095: charval = charval * 16 + digit;
096: x++;
097: }
098: char hexchar = (char) charval;
099: sb.append(hexchar);
100: i = x;
101: } else {
102: int x = i + 2;
103: int charval = 0;
104: while (x < value.length()
105: && value.charAt(x) != ';') {
106: int digit = "0123456789".indexOf(value
107: .charAt(x));
108: if (digit < 0) {
109: return null;
110: }
111: charval = charval * 10 + digit;
112: x++;
113: }
114: char decchar = (char) charval;
115: sb.append(decchar);
116: i = x;
117: }
118: } else if (value.substring(i + 1).startsWith("lt;")) {
119: sb.append('<');
120: i += 3;
121: } else if (value.substring(i + 1).startsWith("gt;")) {
122: sb.append('>');
123: i += 3;
124: } else if (value.substring(i + 1).startsWith("amp;")) {
125: sb.append('&');
126: i += 4;
127: } else if (value.substring(i + 1).startsWith("quot;")) {
128: sb.append('"');
129: i += 5;
130: } else if (value.substring(i + 1).startsWith("apos;")) {
131: sb.append('\'');
132: i += 5;
133: } else {
134: return null;
135: }
136:
137: } else {
138: sb.append(c);
139: }
140: }
141: return sb.toString();
142: }
143:
144: }
145:
146: //
147: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
148: // you may not use this file except in compliance with the License. You may obtain a copy of the
149: // License at http://www.mozilla.org/MPL/
150: //
151: // Software distributed under the License is distributed on an "AS IS" basis,
152: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
153: // See the License for the specific language governing rights and limitations under the License.
154: //
155: // The Original Code is: all this file.
156: //
157: // The Initial Developer of the Original Code is Michael H. Kay.
158: //
159: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
160: //
161: // Contributor(s): none.
162: //
|