n3.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. """
  2. Notation 3 (N3) RDF graph serializer for RDFLib.
  3. """
  4. import warnings
  5. from rdflib.graph import Graph
  6. from rdflib.namespace import OWL, Namespace
  7. from rdflib.plugins.serializers.turtle import OBJECT, SUBJECT, TurtleSerializer
  8. __all__ = ["N3Serializer"]
  9. SWAP_LOG = Namespace("http://www.w3.org/2000/10/swap/log#")
  10. class N3Serializer(TurtleSerializer):
  11. """Notation 3 (N3) RDF graph serializer."""
  12. short_name = "n3"
  13. def __init__(self, store: Graph, parent=None):
  14. super(N3Serializer, self).__init__(store)
  15. self.keywords.update({OWL.sameAs: "=", SWAP_LOG.implies: "=>"})
  16. self.parent = parent
  17. def reset(self):
  18. super(N3Serializer, self).reset()
  19. self._stores = {}
  20. def endDocument(self): # noqa: N802
  21. if not self.parent:
  22. super(N3Serializer, self).endDocument()
  23. def indent(self, modifier=0):
  24. indent = super(N3Serializer, self).indent(modifier)
  25. if self.parent is not None:
  26. indent += self.parent.indent() # modifier)
  27. return indent
  28. def preprocessTriple(self, triple): # noqa: N802
  29. super(N3Serializer, self).preprocessTriple(triple)
  30. if isinstance(triple[0], Graph):
  31. for t in triple[0]:
  32. self.preprocessTriple(t)
  33. if isinstance(triple[1], Graph):
  34. for t in triple[1]:
  35. self.preprocessTriple(t)
  36. if isinstance(triple[2], Graph):
  37. for t in triple[2]:
  38. self.preprocessTriple(t)
  39. def get_pname(self, uri, gen_prefix=True):
  40. qname = None
  41. if self.parent is not None:
  42. qname = self.parent.get_pname(uri, gen_prefix)
  43. if qname is None:
  44. qname = super(N3Serializer, self).get_pname(uri, gen_prefix)
  45. return qname
  46. def getQName(self, uri, gen_prefix=True): # noqa: N802
  47. warnings.warn(
  48. "N3Serializer.getQName is deprecated, use N3Serializer.get_pname instead.",
  49. DeprecationWarning,
  50. stacklevel=2,
  51. )
  52. return self.get_pname(uri, gen_prefix)
  53. def statement(self, subject):
  54. self.subjectDone(subject)
  55. properties = self.buildPredicateHash(subject)
  56. if len(properties) == 0:
  57. return False
  58. return self.s_clause(subject) or super(N3Serializer, self).statement(subject)
  59. def path(self, node, position, newline=False):
  60. if not self.p_clause(node, position):
  61. super(N3Serializer, self).path(node, position, newline)
  62. def s_clause(self, subject):
  63. if isinstance(subject, Graph):
  64. self.write("\n" + self.indent())
  65. self.p_clause(subject, SUBJECT)
  66. self.predicateList(subject)
  67. self.write(" .")
  68. return True
  69. else:
  70. return False
  71. def p_clause(self, node, position):
  72. if isinstance(node, Graph):
  73. self.subjectDone(node)
  74. if position is OBJECT:
  75. self.write(" ")
  76. self.write("{")
  77. self.depth += 1
  78. serializer = N3Serializer(node, parent=self)
  79. # type error: Argument 1 to "serialize" of "TurtleSerializer" has incompatible type "Optional[IO[bytes]]"; expected "IO[bytes]"
  80. serializer.serialize(self.stream) # type: ignore[arg-type]
  81. self.depth -= 1
  82. self.write(self.indent() + "}")
  83. return True
  84. else:
  85. return False