resolving-relative-links.rst 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. .. _advanced.base:
  2. Relative Link Resolution
  3. ========================
  4. Many feed elements and attributes are :abbr:`URI (Uniform Resource Identifier)`\s.
  5. :program:`Universal Feed Parser` resolves relative :abbr:`URI (Uniform Resource Identifier)`\s
  6. according to the `XML:Base <http://www.w3.org/TR/xmlbase/>`_ specification. We'll see how
  7. that works in a minute, but first let's talk about which values are treated as
  8. :abbr:`URI (Uniform Resource Identifier)`\s.
  9. Which Values Are :abbr:`URI (Uniform Resource Identifier)`\s
  10. ------------------------------------------------------------
  11. These feed elements are treated as :abbr:`URI (Uniform Resource Identifier)`\s,
  12. and resolved if they are relative:
  13. * :ref:`reference.entry.author_detail.href`
  14. * :ref:`reference.entry.comments`
  15. * :ref:`reference.entry.contributors.href`
  16. * :ref:`reference.entry.enclosures.href`
  17. * :ref:`reference.entry.id`
  18. * :ref:`reference.entry.license`
  19. * :ref:`reference.entry.link`
  20. * :ref:`reference.entry.links.href`
  21. * :ref:`reference.entry.publisher_detail.href`
  22. * :ref:`reference.entry.source.author_detail.href`
  23. * :ref:`reference.entry.source.contributors.href`
  24. * :ref:`reference.entry.source.links.href`
  25. * :ref:`reference.feed.author_detail.href`
  26. * :ref:`reference.feed.contributors.href`
  27. * :ref:`reference.feed.docs`
  28. * :ref:`reference.feed.generator_detail.href`
  29. * :ref:`reference.feed.id`
  30. * :ref:`reference.feed.image.href`
  31. * :ref:`reference.feed.image.link`
  32. * :ref:`reference.feed.license`
  33. * :ref:`reference.feed.link`
  34. * :ref:`reference.feed.links.href`
  35. * :ref:`reference.feed.publisher_detail.href`
  36. * :ref:`reference.feed.textinput.link`
  37. In addition, several feed elements may contain :abbr:`HTML (HyperText Markup Language)`
  38. or :abbr:`XHTML (Extensible HyperText Markup Language)` markup. Certain elements and
  39. attributes in :abbr:`HTML (HyperText Markup Language)` can be relative
  40. :abbr:`URI (Uniform Resource Identifier)`\s, and :program:`Universal Feed Parser` will
  41. resolve these :abbr:`URI (Uniform Resource Identifier)`\s according to the same rules
  42. as the feed elements listed above.
  43. These feed elements may contain :abbr:`HTML (HyperText Markup Language)` or
  44. :abbr:`XHTML (Extensible HyperText Markup Language)` markup. In Atom feeds,
  45. whether these elements are treated as :abbr:`HTML (HyperText Markup Language)`
  46. depends on the value of the type attribute. In :abbr:`RSS (Rich Site Summary)`
  47. feeds, these values are always treated as :abbr:`HTML (HyperText Markup Language)`.
  48. * :ref:`reference.entry.content.value`
  49. * :ref:`reference.entry.summary` (:ref:`reference.entry.summary_detail.value`)
  50. * :ref:`reference.entry.title` (:ref:`reference.entry.title_detail.value`)
  51. * :ref:`reference.feed.info` (:ref:`reference.feed.info_detail.value`)
  52. * :ref:`reference.feed.rights` (:ref:`reference.feed.rights_detail.value`)
  53. * :ref:`reference.feed.subtitle` (:ref:`reference.feed.subtitle_detail.value`)
  54. * :ref:`reference.feed.title` (:ref:`reference.feed.title_detail.value`)
  55. When any of these feed elements contains :abbr:`HTML (HyperText Markup Language)`
  56. or :abbr:`XHTML (Extensible HyperText Markup Language)` markup, the
  57. following :abbr:`HTML (HyperText Markup Language)` elements are treated as
  58. :abbr:`URI (Uniform Resource Identifier)`\s and are resolved if they are
  59. relative:
  60. * <a href="...">
  61. * <applet codebase="...">
  62. * <area href="...">
  63. * <audio src="...">
  64. * <blockquote cite="...">
  65. * <body background="...">
  66. * <del cite="...">
  67. * <form action="...">
  68. * <frame longdesc="...">
  69. * <frame src="...">
  70. * <head profile="...">
  71. * <iframe longdesc="...">
  72. * <iframe src="...">
  73. * <img longdesc="...">
  74. * <img src="...">
  75. * <img usemap="...">
  76. * <input src="...">
  77. * <input usemap="...">
  78. * <ins cite="...">
  79. * <link href="...">
  80. * <object classid="...">
  81. * <object codebase="...">
  82. * <object data="...">
  83. * <object usemap="...">
  84. * <q cite="...">
  85. * <script src="...">
  86. * <source src="...">
  87. * <video poster="...">
  88. * <video src="...">
  89. How Relative :abbr:`URI (Uniform Resource Identifier)`\s Are Resolved
  90. ---------------------------------------------------------------------
  91. :program:`Universal Feed Parser` resolves relative :abbr:`URI (Uniform Resource Identifier)`\s
  92. according to the `XML:Base <http://www.w3.org/TR/xmlbase/>`_ specification.
  93. This defines a hierarchical inheritance system, where one element can define
  94. the base :abbr:`URI (Uniform Resource Identifier)` for itself and all of its
  95. child elements, using an xml:base attribute. A child element can then override
  96. its parent's base :abbr:`URI (Uniform Resource Identifier)` by redeclaring
  97. xml:base to a different value.
  98. If no xml:base is specified, the feed has a default base :abbr:`URI (Uniform Resource Identifier)`
  99. defined in the Content-Location :abbr:`HTTP (Hypertext Transfer Protocol)` header.
  100. If no Content-Location :abbr:`HTTP (Hypertext Transfer Protocol)` header is
  101. present, the :abbr:`URL (Uniform Resource Locator)` used to retrieve the feed
  102. itself is the default base :abbr:`URI (Uniform Resource Identifier)` for all
  103. relative links within the feed. If the feed was retrieved via an
  104. :abbr:`HTTP (Hypertext Transfer Protocol)` redirect (any :abbr:`HTTP (Hypertext Transfer Protocol)`
  105. 3xx status code), then the final :abbr:`URL (Uniform Resource Locator)` of the
  106. feed is the default base :abbr:`URI (Uniform Resource Identifier)`.
  107. For example, an xml:base on the root-level element sets the base
  108. :abbr:`URI (Uniform Resource Identifier)` for all :abbr:`URI (Uniform Resource Identifier)`\s in the feed.
  109. xml:base on the root-level element
  110. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  111. ::
  112. >>> import feedparser
  113. >>> d = feedparser.parse("http://feedparser.org/docs/examples/base.xml")
  114. >>> d.feed.link
  115. u'http://example.org/index.html'
  116. >>> d.feed.generator_detail.href
  117. u'http://example.org/generator/'
  118. An xml:base attribute on an <entry> overrides the xml:base on the parent <feed>.
  119. Overriding xml:base on an <entry>
  120. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  121. ::
  122. >>> import feedparser
  123. >>> d = feedparser.parse("http://feedparser.org/docs/examples/base.xml")
  124. >>> d.entries[0].link
  125. u'http://example.org/archives/000001.html'
  126. >>> d.entries[0].author_detail.href
  127. u'http://example.org/about/'
  128. An xml:base on <content> overrides the xml:base on the parent <entry>. In
  129. addition, whatever the base :abbr:`URI (Uniform Resource Identifier)` is for
  130. the <content> element (whether defined directly on the <content> element, or
  131. inherited from the parent element) is used as the base :abbr:`URI (Uniform Resource Identifier)`
  132. for the embedded :abbr:`HTML (HyperText Markup Language)`
  133. or :abbr:`XHTML (Extensible HyperText Markup Language)` markup within the
  134. content.
  135. Relative links within embedded :abbr:`HTML (HyperText Markup Language)`
  136. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  137. ::
  138. >>> import feedparser
  139. >>> d = feedparser.parse("http://feedparser.org/docs/examples/base.xml")
  140. >>> d.entries[0].content[0].value
  141. u'<p id="anchor1"><a href="http://example.org/archives/000001.html#anchor2">skip to anchor 2</a></p>
  142. <p>Some content</p>
  143. <p id="anchor2">This is anchor 2</p>'
  144. The xml:base affects other attributes in the element in which it is declared.
  145. xml:base and sibling attributes
  146. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  147. ::
  148. >>> import feedparser
  149. >>> d = feedparser.parse("http://feedparser.org/docs/examples/base.xml")
  150. >>> d.entries[0].links[1].rel
  151. u'service.edit'
  152. >>> d.entries[0].links[1].href
  153. u'http://example.com/api/client/37'
  154. If no xml:base is specified on the root-level element, the default base
  155. :abbr:`URI (Uniform Resource Identifier)` is given in the Content-Location
  156. :abbr:`HTTP (Hypertext Transfer Protocol)` header. This can still be
  157. overridden by any child element that declares an xml:base attribute.
  158. Content-Location :abbr:`HTTP (Hypertext Transfer Protocol)` header
  159. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  160. ::
  161. >>> import feedparser
  162. >>> d = feedparser.parse("http://feedparser.org/docs/examples/http_base.xml")
  163. >>> d.feed.link
  164. u'http://example.org/index.html'
  165. >>> d.entries[0].link
  166. u'http://example.org/archives/000001.html'
  167. Finally, if no root-level xml:base is declared, and no Content-Location
  168. :abbr:`HTTP (Hypertext Transfer Protocol)` header is present, the
  169. :abbr:`URL (Uniform Resource Locator)` of the feed itself is the default base
  170. :abbr:`URI (Uniform Resource Identifier)`. Again, this can still be overridden
  171. by any element that declares an xml:base attribute.
  172. Feed :abbr:`URL (Uniform Resource Locator)` as default base :abbr:`URI (Uniform Resource Identifier)`
  173. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  174. ::
  175. >>> import feedparser
  176. >>> d = feedparser.parse("http://feedparser.org/docs/examples/no_base.xml")
  177. >>> d.feed.link
  178. u'http://feedparser.org/docs/examples/index.html
  179. >>> d.entries[0].link
  180. u'http://example.org/archives/000001.html'
  181. .. _advanced.base.disable:
  182. Disabling Relative :abbr:`URI (Uniform Resource Identifier)`\s Resolution
  183. -------------------------------------------------------------------------
  184. Though not recommended, it is possible to disable :program:`Universal Feed Parser`\'s relative
  185. :abbr:`URI (Uniform Resource Identifier)` resolution by setting feedparser.RESOLVE_RELATIVE_URIS to ``0``.
  186. How to disable relative :abbr:`URI (Uniform Resource Identifier)` resolution
  187. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  188. ::
  189. >>> import feedparser
  190. >>> d = feedparser.parse('http://feedparser.org/docs/examples/base.xml')
  191. >>> d.entries[0].content[0].base
  192. u'http://example.org/archives/000001.html'
  193. >>> print d.entries[0].content[0].value
  194. <p id="anchor1"><a href="http://example.org/archives/000001.html#anchor2">skip to anchor 2</a></p>
  195. <p>Some content</p>
  196. <p id="anchor2">This is anchor 2</p>
  197. >>> feedparser.RESOLVE_RELATIVE_URIS = 0
  198. >>> d2 = feedparser.parse('http://feedparser.org/docs/examples/base.xml')
  199. >>> d2.entries[0].content[0].base
  200. u'http://example.org/archives/000001.html'
  201. >>> print d2.entries[0].content[0].value
  202. <p id="anchor1"><a href="#anchor2">skip to anchor 2</a></p>
  203. <p>Some content</p>
  204. <p id="anchor2">This is anchor 2</p>