/**
   * Set the expression defining the value of the attribute. If this is a constant, and if
   * validation against a schema type was requested, the validation is done immediately.
   *
   * @param select The expression defining the content of the attribute
   * @param config
   * @throws StaticError if the expression is a constant, and validation is requested, and the
   *     constant doesn't match the required type.
   */
  public void setSelect(Expression select, Configuration config) throws StaticError {
    super.setSelect(select, config);

    // Attempt early validation if possible
    if (select instanceof AtomicValue && schemaType != null && !schemaType.isNamespaceSensitive()) {
      CharSequence value = ((AtomicValue) select).getStringValueCS();
      XPathException err =
          schemaType.validateContent(
              value, DummyNamespaceResolver.getInstance(), config.getNameChecker());
      if (err != null) {
        StaticError se =
            new StaticError(
                "Attribute value "
                    + Err.wrap(value, Err.VALUE)
                    + " does not the match the required type "
                    + schemaType.getDescription()
                    + ". "
                    + err.getMessage());
        se.setErrorCode("XTTE1540");
        throw se;
      }
    }

    // If value is fixed, test whether there are any special characters that might need to be
    // escaped when the time comes for serialization
    if (select instanceof StringValue) {
      boolean special = false;
      CharSequence val = ((StringValue) select).getStringValueCS();
      for (int k = 0; k < val.length(); k++) {
        char c = val.charAt(k);
        if ((int) c < 33 || (int) c > 126 || c == '<' || c == '>' || c == '&' || c == '\"') {
          special = true;
          break;
        }
      }
      if (!special) {
        this.options |= ReceiverOptions.NO_SPECIAL_CHARS;
      }
    }

    // If attribute name is xml:id, add whitespace normalization
    if ((nameCode & NamePool.FP_MASK) == StandardNames.XML_ID) {
      Expression[] args = {select};
      FunctionCall fn =
          SystemFunction.makeSystemFunction("normalize-space", 1, config.getNamePool());
      fn.setArguments(args);
      select = fn;
      super.setSelect(select, config);
    }
  }
Пример #2
0
 /**
  * Return the negation of the expression
  *
  * @return the negation of the expression
  */
 public Expression negate() {
   FunctionCall fc = SystemFunction.makeSystemFunction("exists", getArguments());
   fc.setLocationId(getLocationId());
   return fc;
 }
  /**
   * @param result
   * @param expr
   */
  private static void serialize(
      FastStringBuffer result, Expression expr, Map reversePrefixMapping) {
    if (expr instanceof Assignation) {
      // XXX not yet supported
    } else if (expr instanceof AxisExpression) {
      AxisExpression axisExpression = (AxisExpression) expr;
      result.append(Axis.axisName[axisExpression.getAxis()]);
      result.append("::");

      final NodeTest nodeTest = axisExpression.getNodeTest();
      if (nodeTest == null) {
        result.append("node()");
      } else {
        result.append(fixPreFixes(nodeTest.toString(), reversePrefixMapping));
      }
    } else if (expr instanceof BinaryExpression) {
      BinaryExpression binaryExpression = (BinaryExpression) expr;
      result.append('(');
      serialize(result, binaryExpression.getOperands()[0], reversePrefixMapping);
      result.append(Token.tokens[binaryExpression.getOperator()]);
      serialize(result, binaryExpression.getOperands()[1], reversePrefixMapping);
      result.append(')');
    } else if (expr instanceof CompareToIntegerConstant) {
      CompareToIntegerConstant compareToIntegerConstant = (CompareToIntegerConstant) expr;
      result.append('(');
      serialize(result, compareToIntegerConstant.getOperand(), reversePrefixMapping);
      result.append(Token.tokens[compareToIntegerConstant.getComparisonOperator()]);
      result.append(Long.toString(compareToIntegerConstant.getComparand()));
      result.append(')');
    } else if (expr instanceof ConditionalSorter) {
      // XXX not yet supported
    } else if (expr instanceof ContextItemExpression) {
      result.append('.');
    } else if (expr instanceof ErrorExpression) {
      // Error do nothing
    } else if (expr instanceof FilterExpression) {
      FilterExpression filterExpression = (FilterExpression) expr;
      result.append('(');
      serialize(result, filterExpression.getControllingExpression(), reversePrefixMapping);
      result.append('[');
      serialize(result, filterExpression.getFilter(), reversePrefixMapping);
      result.append("])");

    } else if (expr instanceof FunctionCall) {
      FunctionCall functionCall = (FunctionCall) expr;
      StructuredQName name = functionCall.getFunctionName();
      if (name.getPrefix() != null && name.getPrefix().length() > 0) {
        result.append(name.getPrefix());
        result.append(":");
      }
      result.append(name.getLocalName());
      result.append("(");

      Iterator iter = functionCall.iterateSubExpressions();
      boolean first = true;
      while (iter.hasNext()) {
        result.append(first ? "" : ", ");
        SaxonXPathExpressionSerializer.serialize(
            result, (Expression) iter.next(), reversePrefixMapping);
        first = false;
      }

      result.append(")");
    } else if (expr instanceof Instruction) {
      // This is not an XPath expression
    } else if (expr instanceof IntegerRangeTest) {
      // XXX not yet supported
    } else if (expr instanceof IsLastExpression) {
      result.append("position() eq last()");
    } else if (expr instanceof Literal) {
      Literal literal = (Literal) expr;
      result.append(literal.getValue().toString());
    } else if (expr instanceof NumberInstruction) {
      // This is not an XPath expression
    } else if (expr instanceof PathExpression) {
      PathExpression pathExpression = (PathExpression) expr;
      result.append('(');
      serialize(result, pathExpression.getControllingExpression(), reversePrefixMapping);
      result.append('/');
      serialize(result, pathExpression.getControlledExpression(), reversePrefixMapping);
      result.append(')');
    } else if (expr instanceof PatternMatchExpression) {
      // XXX not yet supported
    } else if (expr instanceof PatternSponsor) {
      // XXX not yet supported
    } else if (expr instanceof SimpleContentConstructor) {
      // This is not an XPath expression
    } else if (expr instanceof SimpleExpression) {
      // This is not an XPath expression
    }
    /*
        else if (expr instanceof SimpleMappingExpression) {
    	    // XXX not yet supported
    	}
    */
    else if (expr instanceof ParentNodeExpression) {
      result.append("..");
    } else if (expr instanceof RootExpression) {
      // do nothing
    } else if (expr instanceof SortExpression) {
      // XXX not yet supported
    } else if (expr instanceof TailExpression) {
      // XXX not yet supported
    } else if (expr instanceof TupleExpression) {
      // This is not an XPath expression
    } else if (expr instanceof TupleSorter) {
      // This is not an XPath expression
    } else if (expr instanceof UnaryExpression) {
      UnaryExpression unaryExpression = (UnaryExpression) expr;
      serialize(
          result,
          unaryExpression.getBaseExpression(),
          reversePrefixMapping); // Not sure if this is correct in all cases
    } else if (expr instanceof VariableReference) {
      VariableReference variableReference = (VariableReference) expr;
      String d = variableReference.getDisplayName();
      result.append("$");
      result.append(d == null ? "$" : d);
    }
  }