예제 #1
0
 /*     */ public static String evaluate(
     Object strArg, Object fromArg, Object toArg, Navigator nav)
     /*     */ throws FunctionCallException
       /*     */ {
   /* 162 */ String inStr = StringFunction.evaluate(strArg, nav);
   /* 163 */ String fromStr = StringFunction.evaluate(fromArg, nav);
   /* 164 */ String toStr = StringFunction.evaluate(toArg, nav);
   /*     */
   /* 167 */ Map characterMap = new HashMap();
   /* 168 */ String[] fromCharacters = toUnicodeCharacters(fromStr);
   /* 169 */ String[] toCharacters = toUnicodeCharacters(toStr);
   /* 170 */ int fromLen = fromCharacters.length;
   /* 171 */ int toLen = toCharacters.length;
   /* 172 */ for (int i = 0; i < fromLen; i++) {
     /* 173 */ String cFrom = fromCharacters[i];
     /* 174 */ if (!characterMap.containsKey(cFrom))
     /*     */ {
       /* 179 */ if (i < toLen)
       /*     */ {
         /* 181 */ characterMap.put(cFrom, toCharacters[i]);
         /*     */ }
       /*     */ else
       /*     */ {
         /* 185 */ characterMap.put(cFrom, null);
         /*     */ }
       /*     */ }
     /*     */ }
   /*     */
   /* 190 */ StringBuffer outStr = new StringBuffer(inStr.length());
   /* 191 */ String[] inCharacters = toUnicodeCharacters(inStr);
   /* 192 */ int inLen = inCharacters.length;
   /* 193 */ for (int i = 0; i < inLen; i++) {
     /* 194 */ String cIn = inCharacters[i];
     /* 195 */ if (characterMap.containsKey(cIn)) {
       /* 196 */ String cTo = (String) characterMap.get(cIn);
       /* 197 */ if (cTo != null) /* 198 */ outStr.append(cTo);
       /*     */ }
     /*     */ else
     /*     */ {
       /* 202 */ outStr.append(cIn);
       /*     */ }
     /*     */ }
   /*     */
   /* 206 */ return outStr.toString();
   /*     */ }
예제 #2
0
  /**
   * Returns a substring of an XPath string-value by character index.
   *
   * @param context the context at the point in the expression when the function is called
   * @param args a list that contains two or three items
   * @return a <code>String</code> containing the specifed character subsequence of the original
   *     string or the string-value of the context node
   * @throws FunctionCallException if <code>args</code> has more than three or less than two items
   */
  public Object call(Context context, List args) throws FunctionCallException {
    final int argc = args.size();
    if (argc < 2 || argc > 3) {
      throw new FunctionCallException("substring() requires two or three arguments.");
    }

    final Navigator nav = context.getNavigator();

    final String str = StringFunction.evaluate(args.get(0), nav);
    // The spec doesn't really address this case
    if (str == null) {
      return "";
    }

    final int stringLength = (StringLengthFunction.evaluate(args.get(0), nav)).intValue();

    if (stringLength == 0) {
      return "";
    }

    Double d1 = NumberFunction.evaluate(args.get(1), nav);

    if (d1.isNaN()) {
      return "";
    }
    // Round the value and subtract 1 as Java strings are zero based
    int start = RoundFunction.evaluate(d1, nav).intValue() - 1;

    int substringLength = stringLength;
    if (argc == 3) {
      Double d2 = NumberFunction.evaluate(args.get(2), nav);

      if (!d2.isNaN()) {
        substringLength = RoundFunction.evaluate(d2, nav).intValue();
      } else {
        substringLength = 0;
      }
    }

    if (substringLength < 0) return "";

    int end = start + substringLength;
    if (argc == 2) end = stringLength;

    // negative start is treated as 0
    if (start < 0) {
      start = 0;
    } else if (start > stringLength) {
      return "";
    }

    if (end > stringLength) {
      end = stringLength;
    } else if (end < start) return "";

    if (stringLength == str.length()) {
      // easy case; no surrogate pairs
      return str.substring(start, end);
    } else {
      return unicodeSubstring(str, start, end);
    }
  }