Poor man's XPath library https://pagure.io/shellfu-bash-pxpath

pxpath 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #!/usr/bin/python
  2. #
  3. # A mini-parser to be used where properl XPath tool is not available
  4. #
  5. import os
  6. import sys
  7. import StringIO
  8. import libxml2
  9. STATUS_NOMATCH = 1
  10. STATUS_USAGE = 2
  11. MATCH_FMT = os.environ.get('MATCH_FMT', '%s\n')
  12. def usage():
  13. sys.stderr.write("usage: ./poorxpath //XPATH/EXPR"
  14. " /path/to/result.xml [ns_name:ns_url]...\n")
  15. sys.exit(STATUS_USAGE)
  16. def debug(*msgs):
  17. if os.environ.get('DEBUG') == '1':
  18. [sys.stderr.write('debug: %s\n' % msg) for msg in msgs]
  19. def write(body, origin):
  20. debug('----- BEGIN MATCH (%s) -----' % origin.__class__,
  21. body,
  22. '----- END MATCH (%s) -----' % origin.__class__)
  23. sys.stdout.write(MATCH_FMT % body)
  24. if __name__ == '__main__':
  25. try:
  26. expr = sys.argv[1]
  27. file = sys.argv[2]
  28. except IndexError:
  29. usage()
  30. namespaces = []
  31. for arg in sys.argv[3:]:
  32. name, url = arg.split(':', 1)
  33. namespaces.append((name, url))
  34. doc = libxml2.parseFile(file)
  35. context = doc.xpathNewContext()
  36. [context.xpathRegisterNs(n, u) for n, u in namespaces]
  37. matches = context.xpathEvalExpression(expr)
  38. debug('expr=%r' % expr,
  39. 'matches=%r' % matches)
  40. if isinstance(matches, str):
  41. write(matches, matches)
  42. else:
  43. if not matches:
  44. sys.exit(STATUS_NOMATCH)
  45. for match in matches:
  46. if isinstance(match, libxml2.xmlAttr):
  47. write(match.content, match)
  48. else:
  49. # value = match.serialize()
  50. # debug('value=%r' % value)
  51. write(match.serialize(), match)