Finds an element with a particular identifier. This function allows the direct access to an arbitrarily deeply nested child element by name, without the need to manually traverse through the object tree. The `namespace` argument specifies the kind of element to find. In most cases,
(self, namespace, identifier)
| 397 | return sorted(out_dir) |
| 398 | |
| 399 | def find(self, namespace, identifier): |
| 400 | """Finds an element with a particular identifier. |
| 401 | |
| 402 | This function allows the direct access to an arbitrarily deeply nested |
| 403 | child element by name, without the need to manually traverse through the |
| 404 | object tree. The `namespace` argument specifies the kind of element to |
| 405 | find. In most cases, this corresponds to the element's XML tag name. |
| 406 | However, if an element has multiple specialized tags, then the namespace |
| 407 | corresponds to the tag name of the most general element of that kind. |
| 408 | For example, `namespace='joint'` would search for `<joint>` and |
| 409 | `<freejoint>`, while `namespace='actuator'` would search for `<general>`, |
| 410 | `<motor>`, `<position>`, `<velocity>`, and `<cylinder>`. |
| 411 | |
| 412 | Args: |
| 413 | namespace: A string specifying the namespace being searched. See the |
| 414 | docstring above for explanation. |
| 415 | identifier: The identifier string of the desired element. |
| 416 | |
| 417 | Returns: |
| 418 | An `mjcf.Element` object, or `None` if an element with the specified |
| 419 | identifier is not found. |
| 420 | |
| 421 | Raises: |
| 422 | ValueError: if either `namespace` or `identifier` is not a string, or if |
| 423 | `namespace` is not a valid namespace. |
| 424 | """ |
| 425 | if not isinstance(namespace, str): |
| 426 | raise ValueError( |
| 427 | '`namespace` should be a string: got {!r}'.format(namespace)) |
| 428 | if not isinstance(identifier, str): |
| 429 | raise ValueError( |
| 430 | '`identifier` should be a string: got {!r}'.format(identifier)) |
| 431 | if namespace not in schema.FINDABLE_NAMESPACES: |
| 432 | raise ValueError('{!r} is not a valid namespace. Available: {}.'.format( |
| 433 | namespace, schema.FINDABLE_NAMESPACES)) |
| 434 | if constants.PREFIX_SEPARATOR in identifier: |
| 435 | scope_name = identifier.split(constants.PREFIX_SEPARATOR)[0] |
| 436 | try: |
| 437 | attachment = self.namescope.get('attached_model', scope_name) |
| 438 | found_element = attachment.find( |
| 439 | namespace, identifier[(len(scope_name) + 1):]) |
| 440 | except (KeyError, ValueError): |
| 441 | found_element = None |
| 442 | else: |
| 443 | try: |
| 444 | found_element = self.namescope.get(namespace, identifier) |
| 445 | except KeyError: |
| 446 | found_element = None |
| 447 | if found_element and self._parent: |
| 448 | next_parent = found_element.parent |
| 449 | while next_parent and next_parent != self: |
| 450 | next_parent = next_parent.parent |
| 451 | if not next_parent: |
| 452 | found_element = None |
| 453 | return found_element |
| 454 | |
| 455 | def find_all(self, namespace, |
| 456 | immediate_children_only=False, exclude_attachments=False): |