mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/rss: rss library imported. [ruby-dev:22726]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5566 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
51e6d9061d
commit
8640f16308
47 changed files with 6595 additions and 2 deletions
|
@ -1,3 +1,7 @@
|
|||
Wed Jan 28 12:43:07 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* lib/rss: rss library imported. [ruby-dev:22726]
|
||||
|
||||
Tue Jan 27 15:00:14 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* misc/ruby-mode.el: better support for general delimited
|
||||
|
|
4
config.sub
vendored
4
config.sub
vendored
|
@ -3,7 +3,7 @@
|
|||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2003-01-03'
|
||||
timestamp='2004-01-28'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
|
@ -118,7 +118,7 @@ esac
|
|||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
nto-qnx* | linux-* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
|
|
438
lib/rss/0.9.rb
Normal file
438
lib/rss/0.9.rb
Normal file
|
@ -0,0 +1,438 @@
|
|||
require "rss/rss"
|
||||
|
||||
module RSS
|
||||
|
||||
module RSS09
|
||||
NSPOOL = {}
|
||||
ELEMENTS = []
|
||||
end
|
||||
|
||||
class Rss < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
[
|
||||
["channel", nil],
|
||||
].each do |tag, occurs|
|
||||
install_model(tag, occurs)
|
||||
end
|
||||
|
||||
%w(channel).each do |x|
|
||||
install_have_child_element(x)
|
||||
end
|
||||
|
||||
attr_accessor :rss_version, :version, :encoding, :standalone
|
||||
|
||||
def initialize(rss_version, version=nil, encoding=nil, standalone=nil)
|
||||
super()
|
||||
@rss_version = rss_version
|
||||
@version = version || '1.0'
|
||||
@encoding = encoding
|
||||
@standalone = standalone
|
||||
end
|
||||
|
||||
def output_encoding=(enc)
|
||||
@output_encoding = enc
|
||||
self.converter = Converter.new(@output_encoding, @encoding)
|
||||
end
|
||||
|
||||
def items
|
||||
if @channel
|
||||
@channel.items
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def image
|
||||
if @channel
|
||||
@channel.image
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
rv = <<-EOR
|
||||
#{xmldecl}
|
||||
<rss version="#{@rss_version}"#{ns_declaration}>
|
||||
#{channel_element(false)}
|
||||
#{other_element(false, "\t")}
|
||||
</rss>
|
||||
EOR
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
private
|
||||
def xmldecl
|
||||
rv = "<?xml version='#{@version}'"
|
||||
if @output_encoding or @encoding
|
||||
rv << " encoding='#{@output_encoding or @encoding}'"
|
||||
end
|
||||
rv << " standalone='#{@standalone}'" if @standalone
|
||||
rv << '?>'
|
||||
rv
|
||||
end
|
||||
|
||||
def ns_declaration
|
||||
rv = ''
|
||||
NSPOOL.each do |prefix, uri|
|
||||
prefix = ":#{prefix}" unless prefix.empty?
|
||||
rv << %Q|\n\txmlns#{prefix}="#{uri}"|
|
||||
end
|
||||
rv
|
||||
end
|
||||
|
||||
def children
|
||||
[@channel]
|
||||
end
|
||||
|
||||
class Channel < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
[
|
||||
["title", nil],
|
||||
["link", nil],
|
||||
["description", nil],
|
||||
["language", nil],
|
||||
["copyright", "?"],
|
||||
["managingEditor", "?"],
|
||||
["webMaster", "?"],
|
||||
["rating", "?"],
|
||||
["docs", "?"],
|
||||
["skipDays", "?"],
|
||||
["skipHours", "?"],
|
||||
].each do |x, occurs|
|
||||
install_text_element(x)
|
||||
install_model(x, occurs)
|
||||
end
|
||||
|
||||
[
|
||||
["pubDate", "?"],
|
||||
["lastBuildDate", "?"],
|
||||
].each do |x, occurs|
|
||||
install_date_element(x, 'rfc822')
|
||||
install_model(x, occurs)
|
||||
end
|
||||
|
||||
[
|
||||
["image", nil],
|
||||
["textInput", "?"],
|
||||
["cloud", "?"]
|
||||
].each do |x, occurs|
|
||||
install_have_child_element(x)
|
||||
install_model(x, occurs)
|
||||
end
|
||||
|
||||
[
|
||||
["item", "*"]
|
||||
].each do |x, occurs|
|
||||
install_have_children_element(x)
|
||||
install_model(x, occurs)
|
||||
end
|
||||
|
||||
def initialize()
|
||||
super()
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
rv = <<-EOT
|
||||
<channel>
|
||||
#{title_element(false)}
|
||||
#{link_element(false)}
|
||||
#{description_element(false)}
|
||||
#{language_element(false)}
|
||||
#{copyright_element(false)}
|
||||
#{managingEditor_element(false)}
|
||||
#{webMaster_element(false)}
|
||||
#{rating_element(false)}
|
||||
#{pubDate_element(false)}
|
||||
#{lastBuildDate_element(false)}
|
||||
#{docs_element(false)}
|
||||
#{skipDays_element(false)}
|
||||
#{skipHours_element(false)}
|
||||
#{image_element(false)}
|
||||
#{item_elements(false)}
|
||||
#{textInput_element(false)}
|
||||
#{other_element(false, "\t\t")}
|
||||
</channel>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
private
|
||||
def children
|
||||
[@image, @textInput, @cloud, *@item]
|
||||
end
|
||||
|
||||
class Image < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
%w(url title link width height description).each do |x|
|
||||
install_text_element(x)
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
rv = <<-EOT
|
||||
<image>
|
||||
#{url_element(false)}
|
||||
#{title_element(false)}
|
||||
#{link_element(false)}
|
||||
#{width_element(false)}
|
||||
#{height_element(false)}
|
||||
#{description_element(false)}
|
||||
#{other_element(false, "\t\t\t\t")}
|
||||
</image>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Cloud < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
[
|
||||
["domain", nil, false],
|
||||
["port", nil, false],
|
||||
["path", nil, false],
|
||||
["registerProcedure", nil, false],
|
||||
["protocol", nil ,false],
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
rv = <<-EOT
|
||||
<cloud
|
||||
domain="#{h @domain}"
|
||||
port="#{h @port}"
|
||||
path="#{h @path}"
|
||||
registerProcedure="#{h @registerProcedure}"
|
||||
protocol="#{h @protocol}"/>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Item < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
%w(title link description author comments).each do |x|
|
||||
install_text_element(x)
|
||||
end
|
||||
|
||||
%w(category source enclosure).each do |x|
|
||||
install_have_child_element(x)
|
||||
end
|
||||
|
||||
[
|
||||
["title", '?'],
|
||||
["link", '?'],
|
||||
["description", '?'],
|
||||
["author", '?'],
|
||||
["comments", '?'],
|
||||
["category", '?'],
|
||||
["source", '?'],
|
||||
["enclosure", '?'],
|
||||
].each do |tag, occurs|
|
||||
install_model(tag, occurs)
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
rv = <<-EOT
|
||||
<item>
|
||||
#{title_element(false)}
|
||||
#{link_element(false)}
|
||||
#{description_element(false)}
|
||||
#{author_element(false)}
|
||||
#{category_element(false)}
|
||||
#{comments_element(false)}
|
||||
#{enclosure_element(false)}
|
||||
#{source_element(false)}
|
||||
#{other_element(false, "\t\t\t\t")}
|
||||
</item>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
class Source < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
[
|
||||
["url", nil, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
content_setup
|
||||
|
||||
def initialize(url=nil, content=nil)
|
||||
super()
|
||||
@url = url
|
||||
@content = content
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @url
|
||||
rv = %Q! <source url="#{@url}">!
|
||||
rv << %Q!#{@content}</source>!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["url", true]
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Enclosure < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
[
|
||||
["url", nil, true],
|
||||
["length", nil, true],
|
||||
["type", nil, true],
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
def initialize(url=nil, length=nil, type=nil)
|
||||
super()
|
||||
@url = url
|
||||
@length = length
|
||||
@type = type
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @url and @length and @type
|
||||
rv = %Q!<enclosure url="#{h @url}" !
|
||||
rv << %Q!length="#{h @length}" type="#{h @type}"/>!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["url", true],
|
||||
["length", true],
|
||||
["type", true],
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Category < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
[
|
||||
["domain", nil, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
content_setup
|
||||
|
||||
def initialize(domain=nil, content=nil)
|
||||
super()
|
||||
@domain = domain
|
||||
@content = content
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @domain
|
||||
rv = %Q!<category domain="#{h @domain}">!
|
||||
rv << %Q!#{h @content}</category>!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["domain", true]
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class TextInput < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
%w(title description name link).each do |x|
|
||||
install_text_element(x)
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
rv = <<-EOT
|
||||
<textInput>
|
||||
#{title_element(false)}
|
||||
#{description_element(false)}
|
||||
#{name_element(false)}
|
||||
#{link_element(false)}
|
||||
#{other_element(false, "\t\t\t\t")}
|
||||
</textInput>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if const_defined?(:BaseListener)
|
||||
RSS09::ELEMENTS.each do |x|
|
||||
BaseListener.install_get_text_element(x, nil, "#{x}=")
|
||||
end
|
||||
end
|
||||
|
||||
if const_defined?(:ListenerMixin)
|
||||
module ListenerMixin
|
||||
private
|
||||
def start_rss(tag_name, prefix, attrs, ns)
|
||||
check_ns(tag_name, prefix, ns, nil)
|
||||
|
||||
@rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
|
||||
@last_element = @rss
|
||||
@proc_stack.push Proc.new { |text, tags|
|
||||
@rss.validate_for_stream(tags) if @do_validate
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
652
lib/rss/1.0.rb
Normal file
652
lib/rss/1.0.rb
Normal file
|
@ -0,0 +1,652 @@
|
|||
require "rss/rss"
|
||||
|
||||
module RSS
|
||||
|
||||
module RSS10
|
||||
NSPOOL = {}
|
||||
ELEMENTS = []
|
||||
end
|
||||
|
||||
class RDF < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
TAG_NAME.replace('RDF')
|
||||
|
||||
PREFIX = 'rdf'
|
||||
URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
|
||||
install_ns('', ::RSS::URI)
|
||||
install_ns(PREFIX, URI)
|
||||
|
||||
[
|
||||
["channel", nil],
|
||||
["image", "?"],
|
||||
["item", "+"],
|
||||
["textinput", "?"],
|
||||
].each do |tag, occurs|
|
||||
install_model(tag, occurs)
|
||||
end
|
||||
|
||||
%w(channel image textinput).each do |x|
|
||||
install_have_child_element(x)
|
||||
end
|
||||
|
||||
install_have_children_element("item")
|
||||
|
||||
attr_accessor :rss_version, :version, :encoding, :standalone
|
||||
|
||||
def initialize(version=nil, encoding=nil, standalone=nil)
|
||||
super()
|
||||
@rss_version = '1.0'
|
||||
@version = version || '1.0'
|
||||
@encoding = encoding
|
||||
@standalone = standalone
|
||||
@output_encoding = nil
|
||||
end
|
||||
|
||||
def output_encoding=(enc)
|
||||
@output_encoding = enc
|
||||
self.converter = Converter.new(@output_encoding, @encoding)
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
rv = <<-EORDF
|
||||
#{xmldecl}
|
||||
<#{PREFIX}:RDF#{ns_declaration}>
|
||||
#{channel_element(false)}
|
||||
#{image_element(false)}
|
||||
#{item_elements(false)}
|
||||
#{textinput_element(false)}
|
||||
#{other_element(false, "\t")}
|
||||
</#{PREFIX}:RDF>
|
||||
EORDF
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
private
|
||||
def xmldecl
|
||||
rv = "<?xml version='#{@version}'"
|
||||
if @output_encoding or @encoding
|
||||
rv << " encoding='#{@output_encoding or @encoding}'"
|
||||
end
|
||||
rv << " standalone='#{@standalone}'" if @standalone
|
||||
rv << '?>'
|
||||
rv
|
||||
end
|
||||
|
||||
def ns_declaration
|
||||
rv = ''
|
||||
self.class::NSPOOL.each do |prefix, uri|
|
||||
prefix = ":#{prefix}" unless prefix.empty?
|
||||
rv << %Q|\n\txmlns#{prefix}="#{html_escape(uri)}"|
|
||||
end
|
||||
rv
|
||||
end
|
||||
|
||||
def rdf_validate(tags)
|
||||
_validate(tags, [])
|
||||
end
|
||||
|
||||
def children
|
||||
[@channel, @image, @textinput, *@item]
|
||||
end
|
||||
|
||||
def _tags
|
||||
rv = [
|
||||
[::RSS::URI, "channel"],
|
||||
[::RSS::URI, "image"],
|
||||
].delete_if {|x| send(x[1]).nil?}
|
||||
@item.each do |x|
|
||||
rv << [::RSS::URI, "item"]
|
||||
end
|
||||
rv << [::RSS::URI, "textinput"] if @textinput
|
||||
rv
|
||||
end
|
||||
|
||||
class Seq < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
TAG_NAME.replace('Seq')
|
||||
|
||||
install_have_children_element("li")
|
||||
|
||||
install_must_call_validator('rdf', ::RSS::RDF::URI)
|
||||
|
||||
def initialize(li=[])
|
||||
super()
|
||||
@li = li
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
<<-EOT
|
||||
<#{PREFIX}:Seq>
|
||||
#{li_elements(convert, "\t\t\t\t\t")}
|
||||
#{other_element(convert, "\t\t\t\t\t")}
|
||||
</#{PREFIX}:Seq>
|
||||
EOT
|
||||
end
|
||||
|
||||
private
|
||||
def children
|
||||
@li
|
||||
end
|
||||
|
||||
def rdf_validate(tags)
|
||||
_validate(tags, [["li", '*']])
|
||||
end
|
||||
|
||||
def _tags
|
||||
rv = []
|
||||
@li.each do |x|
|
||||
rv << [URI, "li"]
|
||||
end
|
||||
rv
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Li < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["resource", nil, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
def initialize(resource=nil)
|
||||
super()
|
||||
@resource = resource
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @resource
|
||||
rv = %Q!<#{PREFIX}:li resource="#{h @resource}" />!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["resource", true]
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Channel < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
::RSS::URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["about", URI, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
%w(title link description).each do |x|
|
||||
install_text_element(x)
|
||||
end
|
||||
|
||||
%w(image items textinput).each do |x|
|
||||
install_have_child_element(x)
|
||||
end
|
||||
|
||||
[
|
||||
['title', nil],
|
||||
['link', nil],
|
||||
['description', nil],
|
||||
['image', '?'],
|
||||
['items', nil],
|
||||
['textinput', '?'],
|
||||
].each do |tag, occurs|
|
||||
install_model(tag, occurs)
|
||||
end
|
||||
|
||||
def initialize(about=nil)
|
||||
super()
|
||||
@about = about
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
about = ''
|
||||
about << %Q!#{PREFIX}:about="#{h @about}"! if @about
|
||||
rv = <<-EOT
|
||||
<channel #{about}>
|
||||
#{title_element(false)}
|
||||
#{link_element(false)}
|
||||
#{description_element(false)}
|
||||
#{image_element(false)}
|
||||
#{items_element(false)}
|
||||
#{textinput_element(false)}
|
||||
#{other_element(false, "\t\t")}
|
||||
</channel>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
private
|
||||
def children
|
||||
[@image, @items, @textinput]
|
||||
end
|
||||
|
||||
def _tags
|
||||
[
|
||||
[::RSS::URI, 'title'],
|
||||
[::RSS::URI, 'link'],
|
||||
[::RSS::URI, 'description'],
|
||||
[::RSS::URI, 'image'],
|
||||
[::RSS::URI, 'items'],
|
||||
[::RSS::URI, 'textinput'],
|
||||
].delete_if do |x|
|
||||
send(x[1]).nil?
|
||||
end
|
||||
end
|
||||
|
||||
def _attrs
|
||||
[
|
||||
["about", true]
|
||||
]
|
||||
end
|
||||
|
||||
class Image < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
::RSS::URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["resource", URI, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
def initialize(resource=nil)
|
||||
super()
|
||||
@resource = resource
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @resource
|
||||
rv = %Q!<image #{PREFIX}:resource="#{h @resource}" />!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["resource", true]
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Textinput < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
::RSS::URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["resource", URI, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
def initialize(resource=nil)
|
||||
super()
|
||||
@resource = resource
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @resource
|
||||
rv = %Q|<textinput #{PREFIX}:resource="#{h @resource}" />|
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["resource", true],
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Items < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
Seq = ::RSS::RDF::Seq
|
||||
class Seq
|
||||
unless const_defined?(:Li)
|
||||
Li = ::RSS::RDF::Li
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
::RSS::URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
install_have_child_element("Seq")
|
||||
|
||||
install_must_call_validator('rdf', ::RSS::RDF::URI)
|
||||
|
||||
def initialize(seq=Seq.new)
|
||||
super()
|
||||
@Seq = seq
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
<<-EOT
|
||||
<items>
|
||||
#{Seq_element(convert)}
|
||||
#{other_element(convert, "\t\t\t")}
|
||||
</items>
|
||||
EOT
|
||||
end
|
||||
|
||||
private
|
||||
def children
|
||||
[@Seq]
|
||||
end
|
||||
|
||||
private
|
||||
def _tags
|
||||
rv = []
|
||||
rv << [URI, 'Seq'] unless @Seq.nil?
|
||||
rv
|
||||
end
|
||||
|
||||
def rdf_validate(tags)
|
||||
_validate(tags, [["Seq", nil]])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Image < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
::RSS::URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["about", URI, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
%w(title url link).each do |x|
|
||||
install_text_element(x)
|
||||
end
|
||||
|
||||
[
|
||||
['title', nil],
|
||||
['url', nil],
|
||||
['link', nil],
|
||||
].each do |tag, occurs|
|
||||
install_model(tag, occurs)
|
||||
end
|
||||
|
||||
def initialize(about=nil)
|
||||
super()
|
||||
@about = about
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
about = ''
|
||||
about << %Q!#{PREFIX}:about="#{h @about}"! if @about
|
||||
rv = <<-EOT
|
||||
<image #{about}>
|
||||
#{title_element(false)}
|
||||
#{url_element(false)}
|
||||
#{link_element(false)}
|
||||
#{other_element(false, "\t\t")}
|
||||
</image>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
private
|
||||
def _tags
|
||||
[
|
||||
[::RSS::URI, 'title'],
|
||||
[::RSS::URI, 'url'],
|
||||
[::RSS::URI, 'link'],
|
||||
].delete_if do |x|
|
||||
send(x[1]).nil?
|
||||
end
|
||||
end
|
||||
|
||||
def _attrs
|
||||
[
|
||||
["about", true],
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Item < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
::RSS::URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["about", URI, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
%w(title link description).each do |x|
|
||||
install_text_element(x)
|
||||
end
|
||||
|
||||
[
|
||||
["title", nil],
|
||||
["link", nil],
|
||||
["description", "?"],
|
||||
].each do |tag, occurs|
|
||||
install_model(tag, occurs)
|
||||
end
|
||||
|
||||
def initialize(about=nil)
|
||||
super()
|
||||
@about = about
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
about = ''
|
||||
about << %Q!#{PREFIX}:about="#{h @about}"! if @about
|
||||
rv = <<-EOT
|
||||
<item #{about}>
|
||||
#{title_element(false)}
|
||||
#{link_element(false)}
|
||||
#{description_element(false)}
|
||||
#{other_element(false, "\t\t")}
|
||||
</item>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
private
|
||||
def _tags
|
||||
[
|
||||
[::RSS::URI, 'title'],
|
||||
[::RSS::URI, 'link'],
|
||||
[::RSS::URI, 'description'],
|
||||
].delete_if do |x|
|
||||
send(x[1]).nil?
|
||||
end
|
||||
end
|
||||
|
||||
def _attrs
|
||||
[
|
||||
["about", true],
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Textinput < Element
|
||||
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_uri
|
||||
::RSS::URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["about", URI, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
%w(title description name link).each do |x|
|
||||
install_text_element(x)
|
||||
end
|
||||
|
||||
[
|
||||
["title", nil],
|
||||
["description", nil],
|
||||
["name", nil],
|
||||
["link", nil],
|
||||
].each do |tag, occurs|
|
||||
install_model(tag, occurs)
|
||||
end
|
||||
|
||||
def initialize(about=nil)
|
||||
super()
|
||||
@about = about
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
about = ''
|
||||
about << %Q!#{PREFIX}:about="#{h @about}"! if @about
|
||||
rv = <<-EOT
|
||||
<textinput #{about}>
|
||||
#{title_element(false)}
|
||||
#{description_element(false)}
|
||||
#{name_element(false)}
|
||||
#{link_element(false)}
|
||||
#{other_element(false, "\t\t")}
|
||||
</textinput>
|
||||
EOT
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
end
|
||||
|
||||
private
|
||||
def _tags
|
||||
[
|
||||
[::RSS::URI, 'title'],
|
||||
[::RSS::URI, 'description'],
|
||||
[::RSS::URI, 'name'],
|
||||
[::RSS::URI, 'link'],
|
||||
].delete_if do |x|
|
||||
send(x[1]).nil?
|
||||
end
|
||||
end
|
||||
|
||||
def _attrs
|
||||
[
|
||||
["about", true],
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if const_defined?(:BaseListener)
|
||||
RSS10::ELEMENTS.each do |x|
|
||||
BaseListener.install_get_text_element(x, URI, "#{x}=")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
148
lib/rss/2.0.rb
Normal file
148
lib/rss/2.0.rb
Normal file
|
@ -0,0 +1,148 @@
|
|||
require "rss/0.9"
|
||||
|
||||
module RSS
|
||||
|
||||
class Rss
|
||||
|
||||
URI = "http://backend.userland.com/rss2"
|
||||
|
||||
install_ns('', URI)
|
||||
|
||||
def self.required_uri
|
||||
URI
|
||||
end
|
||||
|
||||
class Channel
|
||||
|
||||
def self.required_uri
|
||||
URI
|
||||
end
|
||||
|
||||
%w(generator ttl).each do |x|
|
||||
install_text_element(x)
|
||||
end
|
||||
|
||||
%w(category).each do |x|
|
||||
install_have_child_element(x)
|
||||
end
|
||||
|
||||
[
|
||||
["image", "?"],
|
||||
].each do |x, occurs|
|
||||
install_model(x, occurs)
|
||||
end
|
||||
|
||||
def other_element(convert, indent='')
|
||||
rv = <<-EOT
|
||||
#{indent}#{category_element(convert)}
|
||||
#{indent}#{generator_element(convert)}
|
||||
#{indent}#{ttl_element(convert)}
|
||||
EOT
|
||||
rv << super
|
||||
end
|
||||
|
||||
Category = Item::Category
|
||||
def Category.required_uri
|
||||
URI
|
||||
end
|
||||
|
||||
class Item
|
||||
|
||||
def self.required_uri
|
||||
URI
|
||||
end
|
||||
|
||||
[
|
||||
["pubDate", '?'],
|
||||
].each do |x, occurs|
|
||||
install_date_element(x, 'rfc822')
|
||||
install_model(x, occurs)
|
||||
end
|
||||
|
||||
[
|
||||
["guid", '?'],
|
||||
].each do |x, occurs|
|
||||
install_have_child_element(x)
|
||||
install_model(x, occurs)
|
||||
end
|
||||
|
||||
def other_element(convert, indent='')
|
||||
rv = <<-EOT
|
||||
#{indent}#{pubDate_element(false)}
|
||||
#{indent}#{guid_element(false)}
|
||||
EOT
|
||||
rv << super
|
||||
end
|
||||
|
||||
class Guid < Element
|
||||
|
||||
include RSS09
|
||||
|
||||
def self.required_uri
|
||||
URI
|
||||
end
|
||||
|
||||
[
|
||||
["isPermaLink", nil, false]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
content_setup
|
||||
|
||||
def initialize(isPermaLink=nil, content=nil)
|
||||
super()
|
||||
@isPermaLink = isPermaLink
|
||||
@content = content
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @content
|
||||
rv = %Q!<guid!
|
||||
rv << %Q! isPermaLink="#{h @isPermaLink}"! if @isPermaLink
|
||||
rv << %Q!>#{h @content}</guid>!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["isPermaLink", false]
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if const_defined?(:BaseListener)
|
||||
RSS09::ELEMENTS.each do |x|
|
||||
BaseListener.install_get_text_element(x, Rss::URI, "#{x}=")
|
||||
end
|
||||
end
|
||||
|
||||
if const_defined?(:ListenerMixin)
|
||||
module ListenerMixin
|
||||
private
|
||||
def start_rss(tag_name, prefix, attrs, ns)
|
||||
check_ns(tag_name, prefix, ns, Rss::URI)
|
||||
|
||||
@rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
|
||||
@last_element = @rss
|
||||
@proc_stack.push Proc.new { |text, tags|
|
||||
@rss.validate_for_stream(tags) if @do_validate
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
47
lib/rss/content.rb
Normal file
47
lib/rss/content.rb
Normal file
|
@ -0,0 +1,47 @@
|
|||
require "rss/1.0"
|
||||
|
||||
module RSS
|
||||
|
||||
CONTENT_PREFIX = 'content'
|
||||
CONTENT_URI = "http://purl.org/rss/1.0/modules/content/"
|
||||
|
||||
RDF.install_ns(CONTENT_PREFIX, CONTENT_URI)
|
||||
|
||||
module ContentModel
|
||||
|
||||
extend BaseModel
|
||||
|
||||
ELEMENTS = []
|
||||
|
||||
%w(encoded).each do |x|
|
||||
install_text_element("#{CONTENT_PREFIX}_#{x}")
|
||||
end
|
||||
|
||||
def content_validate(tags)
|
||||
counter = {}
|
||||
ELEMENTS.each do |x|
|
||||
counter[x] = 0
|
||||
end
|
||||
|
||||
tags.each do |tag|
|
||||
key = "#{CONTENT_PREFIX}_#{tag}"
|
||||
raise UnknownTagError.new(tag, CONTENT_URI) unless counter.has_key?(key)
|
||||
counter[key] += 1
|
||||
raise TooMuchTagError.new(tag, tag_name) if counter[key] > 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class RDF
|
||||
class Item; include ContentModel; end
|
||||
end
|
||||
|
||||
if const_defined? :BaseListener
|
||||
prefix_size = CONTENT_PREFIX.size + 1
|
||||
ContentModel::ELEMENTS.each do |x|
|
||||
BaseListener.install_get_text_element(x[prefix_size..-1], CONTENT_URI, "#{x}=")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
182
lib/rss/converter.rb
Normal file
182
lib/rss/converter.rb
Normal file
|
@ -0,0 +1,182 @@
|
|||
require "rss/utils"
|
||||
|
||||
module RSS
|
||||
|
||||
class Converter
|
||||
|
||||
include Utils
|
||||
|
||||
def initialize(to_enc, from_enc=nil)
|
||||
to_enc = to_enc.downcase.gsub(/-/, '_')
|
||||
from_enc ||= 'utf-8'
|
||||
from_enc = from_enc.downcase.gsub(/-/, '_')
|
||||
if to_enc == from_enc
|
||||
def_same_enc()
|
||||
else
|
||||
if respond_to?("def_to_#{to_enc}_from_#{from_enc}")
|
||||
send("def_to_#{to_enc}_from_#{from_enc}")
|
||||
else
|
||||
def_else_enc(to_enc, from_enc)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def convert(value)
|
||||
value
|
||||
end
|
||||
|
||||
def def_convert()
|
||||
instance_eval(<<-EOC, *get_file_and_line_from_caller(0))
|
||||
def convert(value)
|
||||
if value.kind_of?(String)
|
||||
#{yield('value')}
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_iconv_convert(to_enc, from_enc)
|
||||
begin
|
||||
require "iconv"
|
||||
def_convert do |value|
|
||||
<<-EOC
|
||||
@iconv ||= Iconv.new("#{to_enc}", "#{from_enc}")
|
||||
begin
|
||||
@iconv.iconv(#{value})
|
||||
rescue Iconv::Failure
|
||||
raise ConversionError.new(#{value}, "#{to_enc}", "#{from_enc}")
|
||||
#{value}
|
||||
end
|
||||
EOC
|
||||
end
|
||||
rescue LoadError, ArgumentError, SystemCallError
|
||||
raise UnknownConversionMethodError.new(to_enc, from_enc)
|
||||
end
|
||||
end
|
||||
|
||||
def def_else_enc(to_enc, from_enc)
|
||||
raise UnknownConversionMethodError.new(to_enc, from_enc)
|
||||
end
|
||||
|
||||
def def_same_enc()
|
||||
def_convert do |value|
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_euc_jp_from_utf_8
|
||||
begin
|
||||
require "uconv"
|
||||
def_convert do |value|
|
||||
"Uconv.u8toeuc(#{value})"
|
||||
end
|
||||
rescue LoadError
|
||||
def_iconv_convert('EUC-JP', 'UTF-8')
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_utf_8_from_euc_jp
|
||||
begin
|
||||
require "uconv"
|
||||
def_convert do |value|
|
||||
"Uconv.euctou8(#{value})"
|
||||
end
|
||||
rescue LoadError
|
||||
def_iconv_convert('UTF-8', 'EUC-JP')
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_shift_jis_from_utf_8
|
||||
begin
|
||||
require "uconv"
|
||||
def_convert do |value|
|
||||
"Uconv.u8tosjis(#{value})"
|
||||
end
|
||||
rescue LoadError
|
||||
def_iconv_convert('Shift_JIS', 'UTF-8')
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_utf_8_from_shift_jis
|
||||
begin
|
||||
require "uconv"
|
||||
def_convert do |value|
|
||||
"Uconv.sjistou8(#{value})"
|
||||
end
|
||||
rescue LoadError
|
||||
def_iconv_convert('UTF-8', 'Shift_JIS')
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_euc_jp_from_shift_jis
|
||||
begin
|
||||
require "nkf"
|
||||
rescue LoadError
|
||||
raise UnknownConversionMethodError.new('EUC-JP', 'Shift_JIS')
|
||||
end
|
||||
def_convert do |value|
|
||||
"NKF.nkf('-Se', #{value})"
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_shift_jis_from_euc_jp
|
||||
begin
|
||||
require "nkf"
|
||||
rescue LoadError
|
||||
raise UnknownConversionMethodError.new('Shift_JIS', 'EUC-JP')
|
||||
end
|
||||
def_convert do |value|
|
||||
"NKF.nkf('-Es', #{value})"
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_euc_jp_from_iso_2022_jp
|
||||
begin
|
||||
require "nkf"
|
||||
rescue LoadError
|
||||
raise UnknownConversionMethodError.new('EUC-JP', 'ISO-2022-JP')
|
||||
end
|
||||
def_convert do |value|
|
||||
"NKF.nkf('-Je', #{value})"
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_iso_2022_jp_from_euc_jp
|
||||
begin
|
||||
require "nkf"
|
||||
rescue LoadError
|
||||
raise UnknownConversionMethodError.new('ISO-2022-JP', 'EUC-JP')
|
||||
end
|
||||
def_convert do |value|
|
||||
"NKF.nkf('-Ej', #{value})"
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_utf_8_from_iso_8859_1
|
||||
def_convert do |value|
|
||||
"#{value}.unpack('C*').pack('U*')"
|
||||
end
|
||||
end
|
||||
|
||||
def def_to_iso_8859_1_from_utf_8
|
||||
def_convert do |value|
|
||||
<<-EOC
|
||||
array_utf8 = #{value}.unpack('U*')
|
||||
array_enc = []
|
||||
array_utf8.each do |num|
|
||||
if num <= 0xFF
|
||||
array_enc << num
|
||||
else
|
||||
array_enc.concat "&\#\#{num};".unpack('C*')
|
||||
end
|
||||
end
|
||||
array_enc.pack('C*')
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
56
lib/rss/dublincore.rb
Normal file
56
lib/rss/dublincore.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
require "rss/1.0"
|
||||
|
||||
module RSS
|
||||
|
||||
DC_PREFIX = 'dc'
|
||||
DC_URI = "http://purl.org/dc/elements/1.1/"
|
||||
|
||||
RDF.install_ns(DC_PREFIX, DC_URI)
|
||||
|
||||
module DublincoreModel
|
||||
|
||||
extend BaseModel
|
||||
|
||||
ELEMENTS = []
|
||||
|
||||
%w(title description creator subject publisher
|
||||
contributor type format identifier source
|
||||
language relation coverage rights).each do |x|
|
||||
install_text_element("#{DC_PREFIX}_#{x}")
|
||||
end
|
||||
|
||||
%w(date).each do |x|
|
||||
install_date_element("#{DC_PREFIX}_#{x}", 'iso8601', x)
|
||||
end
|
||||
|
||||
def dc_validate(tags)
|
||||
counter = {}
|
||||
ELEMENTS.each do |x|
|
||||
counter[x] = 0
|
||||
end
|
||||
|
||||
tags.each do |tag|
|
||||
key = "#{DC_PREFIX}_#{tag}"
|
||||
raise UnknownTagError.new(tag, DC_URI) unless counter.has_key?(key)
|
||||
counter[key] += 1
|
||||
raise TooMuchTagError.new(tag, tag_name) if counter[key] > 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class RDF
|
||||
class Channel; include DublincoreModel; end
|
||||
class Image; include DublincoreModel; end
|
||||
class Item; include DublincoreModel; end
|
||||
class Textinput; include DublincoreModel; end
|
||||
end
|
||||
|
||||
if const_defined? :BaseListener
|
||||
prefix_size = DC_PREFIX.size + 1
|
||||
DublincoreModel::ELEMENTS.each do |x|
|
||||
BaseListener.install_get_text_element(x[prefix_size..-1], DC_URI, "#{x}=")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
330
lib/rss/parser.rb
Normal file
330
lib/rss/parser.rb
Normal file
|
@ -0,0 +1,330 @@
|
|||
require "rss/rss"
|
||||
|
||||
module RSS
|
||||
|
||||
class NotWellFormedError < Error
|
||||
attr_reader :line, :element
|
||||
def initialize(line=nil, element=nil)
|
||||
message = "This is not well formed XML"
|
||||
if element or line
|
||||
message << "\nerror occurred"
|
||||
message << " in #{element}" if element
|
||||
message << " at about #{line} line" if line
|
||||
end
|
||||
message << "\n#{yield}" if block_given?
|
||||
super(message)
|
||||
end
|
||||
end
|
||||
|
||||
class XMLParserNotFound < Error
|
||||
def initialize
|
||||
super("available XML parser does not found in " <<
|
||||
"#{AVAILABLE_PARSERS.inspect}.")
|
||||
end
|
||||
end
|
||||
|
||||
class NSError < InvalidRSSError
|
||||
attr_reader :tag, :prefix, :uri
|
||||
def initialize(tag, prefix, require_uri)
|
||||
@tag, @prefix, @uri = tag, prefix, require_uri
|
||||
super("prefix <#{prefix}> doesn't associate uri " <<
|
||||
"<#{require_uri}> in tag <#{tag}>")
|
||||
end
|
||||
end
|
||||
|
||||
class BaseParser
|
||||
|
||||
def initialize(rss)
|
||||
@listener = Listener.new
|
||||
@rss = rss
|
||||
end
|
||||
|
||||
def rss
|
||||
@listener.rss
|
||||
end
|
||||
|
||||
def ignore_unknown_element
|
||||
@listener.ignore_unknown_element
|
||||
end
|
||||
|
||||
def ignore_unknown_element=(new_value)
|
||||
@listener.ignore_unknown_element = new_value
|
||||
end
|
||||
|
||||
def do_validate
|
||||
@listener.do_validate
|
||||
end
|
||||
|
||||
def do_validate=(new_value)
|
||||
@listener.do_validate = new_value
|
||||
end
|
||||
|
||||
def parse
|
||||
if @listener.rss.nil?
|
||||
_parse
|
||||
end
|
||||
@listener.rss
|
||||
end
|
||||
|
||||
class << self
|
||||
def parse(rss, do_validate=true, ignore_unknown_element=true)
|
||||
parser = new(rss)
|
||||
parser.do_validate = do_validate
|
||||
parser.ignore_unknown_element = ignore_unknown_element
|
||||
parser.parse
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class BaseListener
|
||||
|
||||
extend Utils
|
||||
|
||||
class << self
|
||||
|
||||
@@setter = {}
|
||||
def install_setter(uri, tag_name, setter)
|
||||
@@setter[uri] = {} unless @@setter.has_key?(uri)
|
||||
@@setter[uri][tag_name] = setter
|
||||
end
|
||||
|
||||
def setter(uri, tag_name)
|
||||
begin
|
||||
@@setter[uri][tag_name]
|
||||
rescue NameError
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def available_tags(uri)
|
||||
begin
|
||||
@@setter[uri].keys
|
||||
rescue NameError
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def install_get_text_element(name, uri, setter)
|
||||
install_setter(uri, name, setter)
|
||||
def_get_text_element(name, *get_file_and_line_from_caller(1))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def def_get_text_element(name, file, line)
|
||||
unless private_instance_methods(false).include?("start_#{name}")
|
||||
module_eval(<<-EOT, file, line)
|
||||
def start_#{name}(name, prefix, attrs, ns)
|
||||
uri = ns[prefix]
|
||||
if @do_validate
|
||||
tags = self.class.available_tags(uri)
|
||||
unless tags.include?(name)
|
||||
raise UnknownTagError.new(name, uri)
|
||||
end
|
||||
end
|
||||
start_get_text_element(name, prefix, ns, uri)
|
||||
end
|
||||
EOT
|
||||
end
|
||||
send("private", "start_#{name}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module ListenerMixin
|
||||
|
||||
attr_reader :rss
|
||||
|
||||
attr_accessor :ignore_unknown_element
|
||||
attr_accessor :do_validate
|
||||
|
||||
def initialize
|
||||
@rss = nil
|
||||
@ignore_unknown_element = true
|
||||
@do_validate = true
|
||||
@ns_stack = [{}]
|
||||
@tag_stack = [[]]
|
||||
@text_stack = ['']
|
||||
@proc_stack = []
|
||||
@last_element = nil
|
||||
@version = @encoding = @standalone = nil
|
||||
end
|
||||
|
||||
def xmldecl(version, encoding, standalone)
|
||||
@version, @encoding, @standalone = version, encoding, standalone
|
||||
end
|
||||
|
||||
def tag_start(name, attributes)
|
||||
@text_stack.push('')
|
||||
|
||||
ns = @ns_stack.last.dup
|
||||
attrs = {}
|
||||
attributes.each do |n, v|
|
||||
if n =~ /\Axmlns:?/
|
||||
ns[$'] = v # $' is post match
|
||||
else
|
||||
attrs[n] = v
|
||||
end
|
||||
end
|
||||
@ns_stack.push(ns)
|
||||
|
||||
prefix, local = split_name(name)
|
||||
@tag_stack.last.push([ns[prefix], local])
|
||||
@tag_stack.push([])
|
||||
if respond_to?("start_#{local}", true)
|
||||
send("start_#{local}", local, prefix, attrs, ns.dup)
|
||||
else
|
||||
start_else_element(local, prefix, attrs, ns.dup)
|
||||
end
|
||||
end
|
||||
|
||||
def tag_end(name)
|
||||
if $DEBUG
|
||||
p "end tag #{name}"
|
||||
p @tag_stack
|
||||
end
|
||||
text = @text_stack.pop
|
||||
tags = @tag_stack.pop
|
||||
pr = @proc_stack.pop
|
||||
pr.call(text, tags) unless pr.nil?
|
||||
end
|
||||
|
||||
def text(data)
|
||||
@text_stack.last << data
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def start_RDF(tag_name, prefix, attrs, ns)
|
||||
check_ns(tag_name, prefix, ns, RDF::URI)
|
||||
|
||||
@rss = RDF.new(@version, @encoding, @standalone)
|
||||
@rss.do_validate = @do_validate
|
||||
@last_element = @rss
|
||||
@proc_stack.push Proc.new { |text, tags|
|
||||
@rss.validate_for_stream(tags) if @do_validate
|
||||
}
|
||||
end
|
||||
|
||||
def start_else_element(local, prefix, attrs, ns)
|
||||
class_name = local[0,1].upcase << local[1..-1]
|
||||
current_class = @last_element.class
|
||||
begin
|
||||
# if current_class.const_defined?(class_name)
|
||||
next_class = current_class.const_get(class_name)
|
||||
start_have_something_element(local, prefix, attrs, ns, next_class)
|
||||
rescue NameError
|
||||
# else
|
||||
if @ignore_unknown_element
|
||||
@proc_stack.push(nil)
|
||||
else
|
||||
parent = "ROOT ELEMENT???"
|
||||
begin
|
||||
parent = current_class::TAG_NAME
|
||||
rescue NameError
|
||||
end
|
||||
raise NotExceptedTagError.new(local, parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
NAMESPLIT = /^(?:([\w:][-\w\d.]*):)?([\w:][-\w\d.]*)/
|
||||
def split_name(name)
|
||||
name =~ NAMESPLIT
|
||||
[$1 || '', $2]
|
||||
end
|
||||
|
||||
def check_ns(tag_name, prefix, ns, require_uri)
|
||||
if @do_validate
|
||||
if ns[prefix] == require_uri
|
||||
#ns.delete(prefix)
|
||||
else
|
||||
raise NSError.new(tag_name, prefix, require_uri)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def start_get_text_element(tag_name, prefix, ns, required_uri)
|
||||
@proc_stack.push Proc.new {|text, tags|
|
||||
setter = self.class.setter(required_uri, tag_name)
|
||||
setter ||= "#{tag_name}="
|
||||
if @last_element.respond_to?(setter)
|
||||
@last_element.send(setter, text.to_s)
|
||||
else
|
||||
if @do_validate and not @ignore_unknown_element
|
||||
raise NotExceptedTagError.new(tag_name, @last_element.tag_name)
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def start_have_something_element(tag_name, prefix, attrs, ns, klass)
|
||||
|
||||
check_ns(tag_name, prefix, ns, klass.required_uri)
|
||||
|
||||
args = []
|
||||
|
||||
klass.get_attributes.each do |a_name, a_uri, required|
|
||||
|
||||
if a_uri
|
||||
for prefix, uri in ns
|
||||
if uri == a_uri
|
||||
val = attrs["#{prefix}:#{a_name}"]
|
||||
break if val
|
||||
end
|
||||
end
|
||||
else
|
||||
val = attrs[a_name]
|
||||
end
|
||||
|
||||
if @do_validate and required and val.nil?
|
||||
raise MissingAttributeError.new(tag_name, a_name)
|
||||
end
|
||||
|
||||
args << val
|
||||
end
|
||||
|
||||
previous = @last_element
|
||||
next_element = klass.send(:new, *args)
|
||||
next_element.do_validate = @do_validate
|
||||
setter = ""
|
||||
setter << "#{klass.required_prefix}_" if klass.required_prefix
|
||||
setter << "#{tag_name}="
|
||||
@last_element.send(setter, next_element)
|
||||
@last_element = next_element
|
||||
@proc_stack.push Proc.new { |text, tags|
|
||||
p @last_element.class if $DEBUG
|
||||
@last_element.content = text if klass.have_content?
|
||||
@last_element.validate_for_stream(tags) if @do_validate
|
||||
@last_element = previous
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
unless const_defined? :AVAILABLE_PARSERS
|
||||
AVAILABLE_PARSERS = [
|
||||
"rss/xmlparser",
|
||||
"rss/xmlscanner",
|
||||
"rss/rexmlparser",
|
||||
]
|
||||
end
|
||||
|
||||
loaded = false
|
||||
AVAILABLE_PARSERS.each do |parser|
|
||||
begin
|
||||
require parser
|
||||
loaded = true
|
||||
break
|
||||
rescue LoadError
|
||||
end
|
||||
end
|
||||
|
||||
unless loaded
|
||||
raise XMLParserNotFound
|
||||
end
|
||||
end
|
||||
|
43
lib/rss/rexmlparser.rb
Normal file
43
lib/rss/rexmlparser.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
require "rexml/document"
|
||||
require "rexml/streamlistener"
|
||||
|
||||
/\A(\d+)\.(\d+).\d+\z/ =~ REXML::Version
|
||||
if $1.to_i < 2 or ($1.to_i == 2 and $2.to_i < 5)
|
||||
raise LoadError
|
||||
end
|
||||
|
||||
module RSS
|
||||
|
||||
class Parser < BaseParser
|
||||
|
||||
private
|
||||
def _parse
|
||||
begin
|
||||
REXML::Document.parse_stream(@rss, @listener)
|
||||
rescue RuntimeError => e
|
||||
raise NotWellFormedError.new{e.message}
|
||||
rescue REXML::ParseException => e
|
||||
context = e.context
|
||||
line = context[0] if context
|
||||
raise NotWellFormedError.new(line){e.message}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Listener < BaseListener
|
||||
|
||||
include REXML::StreamListener
|
||||
include ListenerMixin
|
||||
|
||||
|
||||
def xmldecl(version, encoding, standalone)
|
||||
super
|
||||
# Encoding is converted to UTF-8 when REXML parse XML.
|
||||
@encoding = 'UTF-8'
|
||||
end
|
||||
|
||||
alias_method(:cdata, :text)
|
||||
end
|
||||
|
||||
end
|
536
lib/rss/rss.rb
Normal file
536
lib/rss/rss.rb
Normal file
|
@ -0,0 +1,536 @@
|
|||
require "time"
|
||||
|
||||
require "rss/utils"
|
||||
require "rss/converter"
|
||||
|
||||
module RSS
|
||||
|
||||
VERSION = "0.0.7"
|
||||
|
||||
class Error < StandardError; end
|
||||
|
||||
class OverlappedPrefixError < Error
|
||||
attr_reader :prefix
|
||||
def initialize(prefix)
|
||||
@prefix = prefix
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidRSSError < Error; end
|
||||
|
||||
class MissingTagError < InvalidRSSError
|
||||
attr_reader :tag, :parent
|
||||
def initialize(tag, parent)
|
||||
@tag, @parent = tag, parent
|
||||
super("tag <#{tag}> is missing in tag <#{parent}>")
|
||||
end
|
||||
end
|
||||
|
||||
class TooMuchTagError < InvalidRSSError
|
||||
attr_reader :tag, :parent
|
||||
def initialize(tag, parent)
|
||||
@tag, @parent = tag, parent
|
||||
super("tag <#{tag}> is too much in tag <#{parent}>")
|
||||
end
|
||||
end
|
||||
|
||||
class MissingAttributeError < InvalidRSSError
|
||||
attr_reader :tag, :attribute
|
||||
def initialize(tag, attribute)
|
||||
@tag, @attribute = tag, attribute
|
||||
super("attribute <#{attribute}> is missing in tag <#{tag}>")
|
||||
end
|
||||
end
|
||||
|
||||
class UnknownTagError < InvalidRSSError
|
||||
attr_reader :tag, :uri
|
||||
def initialize(tag, uri)
|
||||
@tag, @uri = tag, uri
|
||||
super("tag <#{tag}> is unknown in namespace specified by uri <#{uri}>")
|
||||
end
|
||||
end
|
||||
|
||||
class NotExceptedTagError < InvalidRSSError
|
||||
attr_reader :tag, :parent
|
||||
def initialize(tag, parent)
|
||||
@tag, @parent = tag, parent
|
||||
super("tag <#{tag}> is not expected in tag <#{parent}>")
|
||||
end
|
||||
end
|
||||
|
||||
class NotAvailableValueError < InvalidRSSError
|
||||
attr_reader :tag, :value
|
||||
def initialize(tag, value)
|
||||
@tag, @value = tag, value
|
||||
super("value <#{value}> of tag <#{tag}> is not available.")
|
||||
end
|
||||
end
|
||||
|
||||
class UnknownConversionMethodError < Error
|
||||
attr_reader :to, :from
|
||||
def initialize(to, from)
|
||||
@to = from
|
||||
@from = from
|
||||
super("can't convert to #{to} from #{from}.")
|
||||
end
|
||||
end
|
||||
# for backward compatibility
|
||||
UnknownConvertMethod = UnknownConversionMethodError
|
||||
|
||||
class ConversionError < Error
|
||||
attr_reader :string, :to, :from
|
||||
def initialize(string, to, from)
|
||||
@string = string
|
||||
@to = from
|
||||
@from = from
|
||||
super("can't convert #{@string} to #{to} from #{from}.")
|
||||
end
|
||||
end
|
||||
|
||||
module BaseModel
|
||||
|
||||
include Utils
|
||||
|
||||
def install_have_child_element(name)
|
||||
attr_accessor name
|
||||
install_element(name) do |n, elem_name|
|
||||
<<-EOC
|
||||
if @#{n}
|
||||
"\#{indent}\#{@#{n}.to_s(convert)}"
|
||||
else
|
||||
''
|
||||
end
|
||||
EOC
|
||||
end
|
||||
end
|
||||
alias_method(:install_have_attribute_element, :install_have_child_element)
|
||||
|
||||
def install_have_children_element(name, postfix="s")
|
||||
def_children_accessor(name, postfix)
|
||||
add_have_children_element(name)
|
||||
install_element(name, postfix) do |n, elem_name|
|
||||
<<-EOC
|
||||
rv = ''
|
||||
@#{n}.each do |x|
|
||||
rv << "\#{indent}\#{x.to_s(convert)}"
|
||||
end
|
||||
rv
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
def install_text_element(name)
|
||||
self::ELEMENTS << name
|
||||
attr_writer name
|
||||
convert_attr_reader name
|
||||
install_element(name) do |n, elem_name|
|
||||
<<-EOC
|
||||
if @#{n}
|
||||
rv = "\#{indent}<#{elem_name}>"
|
||||
value = html_escape(@#{n})
|
||||
if convert and @converter
|
||||
rv << @converter.convert(value)
|
||||
else
|
||||
rv << value
|
||||
end
|
||||
rv << "</#{elem_name}>"
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
def install_date_element(name, type, disp_name=name)
|
||||
self::ELEMENTS << name
|
||||
|
||||
# accessor
|
||||
convert_attr_reader name
|
||||
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
|
||||
def #{name}=(new_value)
|
||||
if new_value.kind_of?(Time)
|
||||
@#{name} = new_value
|
||||
else
|
||||
if @do_validate
|
||||
begin
|
||||
@#{name} = Time.send('#{type}', new_value)
|
||||
rescue ArgumentError
|
||||
raise NotAvailableValueError.new('#{disp_name}', new_value)
|
||||
end
|
||||
elsif /\\A\\s*\\z/ !~ new_value.to_s
|
||||
@#{name} = Time.parse(new_value)
|
||||
else
|
||||
@#{name} = nil
|
||||
end
|
||||
end
|
||||
|
||||
# Is it need?
|
||||
if @#{name}
|
||||
class << @#{name}
|
||||
alias_method(:_to_s, :to_s) unless respond_to?(:_to_s)
|
||||
alias_method(:to_s, :#{type})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
EOC
|
||||
|
||||
install_element(name) do |n, elem_name|
|
||||
<<-EOC
|
||||
if @#{n}
|
||||
rv = "\#{indent}<#{elem_name}>"
|
||||
value = html_escape(@#{n}.#{type})
|
||||
if convert and @converter
|
||||
rv << @converter.convert(value)
|
||||
else
|
||||
rv << value
|
||||
end
|
||||
rv << "</#{elem_name}>"
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
def install_element(name, postfix="")
|
||||
elem_name = name.sub('_', ':')
|
||||
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
|
||||
def #{name}_element#{postfix}(convert=true, indent='')
|
||||
#{yield(name, elem_name)}
|
||||
end
|
||||
private :#{name}_element#{postfix}
|
||||
EOC
|
||||
end
|
||||
|
||||
def convert_attr_reader(*attrs)
|
||||
attrs.each do |attr|
|
||||
attr = attr.id2name if attr.kind_of?(Integer)
|
||||
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
|
||||
def #{attr}
|
||||
if @converter
|
||||
@converter.convert(@#{attr})
|
||||
else
|
||||
@#{attr}
|
||||
end
|
||||
end
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
def def_children_accessor(accessor_name, postfix="s")
|
||||
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
|
||||
def #{accessor_name}#{postfix}
|
||||
@#{accessor_name}
|
||||
end
|
||||
|
||||
def #{accessor_name}(*args)
|
||||
if args.empty?
|
||||
@#{accessor_name}.first
|
||||
else
|
||||
@#{accessor_name}.send("[]", *args)
|
||||
end
|
||||
end
|
||||
|
||||
def #{accessor_name}=(*args)
|
||||
if args.size == 1
|
||||
@#{accessor_name}.push(args[0])
|
||||
else
|
||||
@#{accessor_name}.send("[]=", *args)
|
||||
end
|
||||
end
|
||||
alias_method(:set_#{accessor_name}, :#{accessor_name}=)
|
||||
EOC
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
URI = "http://purl.org/rss/1.0/"
|
||||
|
||||
class Element
|
||||
|
||||
extend BaseModel
|
||||
include Utils
|
||||
|
||||
class << self
|
||||
|
||||
def inherited(klass)
|
||||
klass.module_eval(<<-EOC)
|
||||
public
|
||||
|
||||
TAG_NAME = name.split('::').last.downcase
|
||||
|
||||
|
||||
@@must_call_validators = {::RSS::URI => ''}
|
||||
|
||||
def self.must_call_validators
|
||||
@@must_call_validators
|
||||
end
|
||||
|
||||
def self.install_must_call_validator(prefix, uri)
|
||||
@@must_call_validators[uri] = prefix
|
||||
end
|
||||
|
||||
@@model = []
|
||||
|
||||
def self.model
|
||||
@@model
|
||||
end
|
||||
|
||||
def self.install_model(tag, occurs=nil)
|
||||
if m = @@model.find {|t, o| t == tag}
|
||||
m[1] = occurs
|
||||
else
|
||||
@@model << [tag, occurs]
|
||||
end
|
||||
end
|
||||
|
||||
@@get_attributes = []
|
||||
|
||||
def self.get_attributes()
|
||||
@@get_attributes
|
||||
end
|
||||
|
||||
def self.install_get_attribute(name, uri, required=true)
|
||||
attr_writer name
|
||||
convert_attr_reader name
|
||||
@@get_attributes << [name, uri, required]
|
||||
end
|
||||
|
||||
@@have_content = false
|
||||
|
||||
def self.content_setup
|
||||
attr_writer :content
|
||||
convert_attr_reader :content
|
||||
@@have_content = true
|
||||
end
|
||||
|
||||
def self.have_content?
|
||||
@@have_content
|
||||
end
|
||||
|
||||
@@have_children_elements = []
|
||||
|
||||
def self.have_children_elements
|
||||
@@have_children_elements
|
||||
end
|
||||
|
||||
def self.add_have_children_element(variable_name)
|
||||
@@have_children_elements << variable_name
|
||||
end
|
||||
|
||||
EOC
|
||||
end
|
||||
|
||||
def required_prefix
|
||||
nil
|
||||
end
|
||||
|
||||
def required_uri
|
||||
nil
|
||||
end
|
||||
|
||||
def install_ns(prefix, uri)
|
||||
if self::NSPOOL.has_key?(prefix)
|
||||
raise OverlappedPrefixError.new(prefix)
|
||||
end
|
||||
self::NSPOOL[prefix] = uri
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
attr_accessor :do_validate
|
||||
|
||||
def initialize(do_validate=true)
|
||||
@do_validate = do_validate
|
||||
initialize_have_children_elements
|
||||
end
|
||||
|
||||
def tag_name
|
||||
self.class::TAG_NAME
|
||||
end
|
||||
|
||||
def converter=(converter)
|
||||
@converter = converter
|
||||
children.each do |child|
|
||||
child.converter = converter unless child.nil?
|
||||
end
|
||||
end
|
||||
|
||||
def validate
|
||||
validate_attribute
|
||||
__validate
|
||||
end
|
||||
|
||||
def validate_for_stream(tags)
|
||||
__validate(tags, false)
|
||||
end
|
||||
|
||||
private
|
||||
def initialize_have_children_elements
|
||||
self.class.have_children_elements.each do |variable_name|
|
||||
instance_eval("@#{variable_name} = []")
|
||||
end
|
||||
end
|
||||
|
||||
# not String class children.
|
||||
def children
|
||||
[]
|
||||
end
|
||||
|
||||
# default #validate() argument.
|
||||
def _tags
|
||||
[]
|
||||
end
|
||||
|
||||
def _attrs
|
||||
[]
|
||||
end
|
||||
|
||||
def __validate(tags=_tags, recursive=true)
|
||||
if recursive
|
||||
children.compact.each do |child|
|
||||
child.validate
|
||||
end
|
||||
end
|
||||
must_call_validators = self.class::must_call_validators
|
||||
tags = tag_filter(tags.dup)
|
||||
p tags if $DEBUG
|
||||
self.class::NSPOOL.each do |prefix, uri|
|
||||
if tags.has_key?(uri) and !must_call_validators.has_key?(uri)
|
||||
meth = "#{prefix}_validate"
|
||||
send(meth, tags[uri]) if respond_to?(meth, true)
|
||||
end
|
||||
end
|
||||
must_call_validators.each do |uri, prefix|
|
||||
send("#{prefix}_validate", tags[uri])
|
||||
end
|
||||
end
|
||||
|
||||
def validate_attribute
|
||||
_attrs.each do |a_name, required|
|
||||
if required and send(a_name).nil?
|
||||
raise MissingAttributeError.new(self.class::TAG_NAME, a_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def other_element(convert, indent='')
|
||||
rv = ''
|
||||
private_methods.each do |meth|
|
||||
if /\A([^_]+)_[^_]+_elements?\z/ =~ meth and
|
||||
self.class::NSPOOL.has_key?($1)
|
||||
res = send(meth, convert)
|
||||
rv << "#{indent}#{res}\n" if /\A\s*\z/ !~ res
|
||||
end
|
||||
end
|
||||
rv
|
||||
end
|
||||
|
||||
def _validate(tags, model=self.class.model)
|
||||
count = 1
|
||||
do_redo = false
|
||||
not_shift = false
|
||||
tag = nil
|
||||
|
||||
model.each_with_index do |elem, i|
|
||||
|
||||
if $DEBUG
|
||||
p "before"
|
||||
p tags
|
||||
p elem
|
||||
end
|
||||
|
||||
if not_shift
|
||||
not_shift = false
|
||||
else
|
||||
begin
|
||||
tag = tags.shift
|
||||
rescue NameError
|
||||
end
|
||||
end
|
||||
|
||||
if $DEBUG
|
||||
p "mid"
|
||||
p count
|
||||
end
|
||||
|
||||
case elem[1]
|
||||
when '?'
|
||||
if count > 2
|
||||
raise TooMuchTagError.new(elem[0], tag_name)
|
||||
else
|
||||
if elem[0] == tag
|
||||
do_redo = true
|
||||
else
|
||||
not_shift = true
|
||||
end
|
||||
end
|
||||
when '*'
|
||||
if elem[0] == tag
|
||||
do_redo = true
|
||||
else
|
||||
not_shift = true
|
||||
end
|
||||
when '+'
|
||||
if elem[0] == tag
|
||||
do_redo = true
|
||||
else
|
||||
if count > 1
|
||||
not_shift = true
|
||||
else
|
||||
raise MissingTagError.new(elem[0], tag_name)
|
||||
end
|
||||
end
|
||||
else
|
||||
if elem[0] == tag
|
||||
begin
|
||||
if model[i+1][0] != elem[0] and tags.first == elem[0]
|
||||
raise TooMuchTagError.new(elem[0], tag_name)
|
||||
end
|
||||
rescue NameError # for model[i+1][0] and tags.first
|
||||
end
|
||||
else
|
||||
raise MissingTagError.new(elem[0], tag_name)
|
||||
end
|
||||
end
|
||||
|
||||
if $DEBUG
|
||||
p "after"
|
||||
p not_shift
|
||||
p do_redo
|
||||
p tag
|
||||
end
|
||||
|
||||
if do_redo
|
||||
do_redo = false
|
||||
count += 1
|
||||
redo
|
||||
else
|
||||
count = 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if !tags.nil? and !tags.empty?
|
||||
raise NotExceptedTagError.new(tag, tag_name)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def tag_filter(tags)
|
||||
rv = {}
|
||||
tags.each do |tag|
|
||||
rv[tag[0]] = [] unless rv.has_key?(tag[0])
|
||||
rv[tag[0]].push(tag[1])
|
||||
end
|
||||
rv
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
81
lib/rss/syndication.rb
Normal file
81
lib/rss/syndication.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
require "rss/1.0"
|
||||
|
||||
module RSS
|
||||
|
||||
SY_PREFIX = 'sy'
|
||||
SY_URI = "http://purl.org/rss/1.0/modules/syndication/"
|
||||
|
||||
RDF.install_ns(SY_PREFIX, SY_URI)
|
||||
|
||||
module SyndicationModel
|
||||
|
||||
extend BaseModel
|
||||
|
||||
ELEMENTS = []
|
||||
|
||||
%w(updatePeriod updateFrequency).each do |x|
|
||||
install_text_element("#{SY_PREFIX}_#{x}")
|
||||
end
|
||||
|
||||
%w(updateBase).each do |x|
|
||||
install_date_element("#{SY_PREFIX}_#{x}", 'iso8601', x)
|
||||
end
|
||||
|
||||
def sy_validate(tags)
|
||||
counter = {}
|
||||
ELEMENTS.each do |x|
|
||||
counter[x] = 0
|
||||
end
|
||||
|
||||
tags.each do |tag|
|
||||
key = "#{SY_PREFIX}_#{tag}"
|
||||
raise UnknownTagError.new(tag, SY_URI) unless counter.has_key?(key)
|
||||
counter[key] += 1
|
||||
raise TooMuchTagError.new(tag, tag_name) if counter[key] > 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
alias_method(:_sy_updatePeriod=, :sy_updatePeriod=)
|
||||
def sy_updatePeriod=(new_value)
|
||||
new_value = new_value.strip
|
||||
validate_sy_updatePeriod(new_value) if @do_validate
|
||||
self._sy_updatePeriod = new_value
|
||||
end
|
||||
|
||||
alias_method(:_sy_updateFrequency=, :sy_updateFrequency=)
|
||||
def sy_updateFrequency=(new_value)
|
||||
new_value = new_value.strip
|
||||
validate_sy_updateFrequency(new_value) if @do_validate
|
||||
self._sy_updateFrequency = new_value.to_i
|
||||
end
|
||||
|
||||
private
|
||||
SY_UPDATEPERIOD_AVAILABLE_VALUES = %w(hourly daily weekly monthly yearly)
|
||||
def validate_sy_updatePeriod(value)
|
||||
unless SY_UPDATEPERIOD_AVAILABLE_VALUES.include?(value)
|
||||
raise NotAvailableValueError.new("updatePeriod", value)
|
||||
end
|
||||
end
|
||||
|
||||
SY_UPDATEFREQUENCY_AVAILABLE_RE = /\A\s*\+?\d+\s*\z/
|
||||
def validate_sy_updateFrequency(value)
|
||||
if SY_UPDATEFREQUENCY_AVAILABLE_RE !~ value
|
||||
raise NotAvailableValueError.new("updateFrequency", value)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class RDF
|
||||
class Channel; include SyndicationModel; end
|
||||
end
|
||||
|
||||
if const_defined? :BaseListener
|
||||
prefix_size = SY_PREFIX.size + 1
|
||||
SyndicationModel::ELEMENTS.each do |x|
|
||||
BaseListener.install_get_text_element(x[prefix_size..-1], SY_URI, "#{x}=")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
32
lib/rss/taxonomy.rb
Normal file
32
lib/rss/taxonomy.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Experimental
|
||||
|
||||
require "rss/1.0"
|
||||
|
||||
module RSS
|
||||
|
||||
TAXO_PREFIX = "taxo"
|
||||
TAXO_NS = "http://purl.org/rss/1.0/modules/taxonomy/"
|
||||
|
||||
Element.install_ns(TAXO_PREFIX, TAXO_NS)
|
||||
|
||||
TAXO_ELEMENTS = []
|
||||
|
||||
%w(link).each do |x|
|
||||
if const_defined? :Listener
|
||||
Listener.install_get_text_element(x, TAXO_NS, "#{TAXO_PREFIX}_#{x}=")
|
||||
end
|
||||
TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{x}"
|
||||
end
|
||||
|
||||
module TaxonomyModel
|
||||
attr_writer *%w(title description creator subject publisher
|
||||
contributor date format identifier source
|
||||
language relation coverage rights).collect{|x| "#{TAXO_PREFIX}_#{x}"}
|
||||
end
|
||||
|
||||
class Channel; extend TaxonomyModel; end
|
||||
class Item; extend TaxonomyModel; end
|
||||
class Image; extend TaxonomyModel; end
|
||||
class TextInput; extend TaxonomyModel; end
|
||||
|
||||
end
|
235
lib/rss/trackback.rb
Normal file
235
lib/rss/trackback.rb
Normal file
|
@ -0,0 +1,235 @@
|
|||
# ATTENSION:
|
||||
# TrackBack handling API MUST be CHANGED!!!!
|
||||
|
||||
require 'rss/1.0'
|
||||
require 'rss/2.0'
|
||||
|
||||
module RSS
|
||||
|
||||
TRACKBACK_PREFIX = 'trackback'
|
||||
TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/'
|
||||
|
||||
RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)
|
||||
Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)
|
||||
|
||||
module BaseTrackBackModel
|
||||
def trackback_validate(tags)
|
||||
raise unless @do_validate
|
||||
counter = {}
|
||||
%w(ping about).each do |x|
|
||||
counter["#{TRACKBACK_PREFIX}_#{x}"] = 0
|
||||
end
|
||||
|
||||
tags.each do |tag|
|
||||
key = "#{TRACKBACK_PREFIX}_#{tag}"
|
||||
raise UnknownTagError.new(tag, TRACKBACK_URI) unless counter.has_key?(key)
|
||||
counter[key] += 1
|
||||
if tag != "about" and counter[key] > 1
|
||||
raise TooMuchTagError.new(tag, tag_name)
|
||||
end
|
||||
end
|
||||
|
||||
if counter["#{TRACKBACK_PREFIX}_ping"].zero? and
|
||||
counter["#{TRACKBACK_PREFIX}_about"].nonzero?
|
||||
raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module TrackBackModel10
|
||||
extend BaseModel
|
||||
include BaseTrackBackModel
|
||||
|
||||
def self.append_features(klass)
|
||||
super
|
||||
|
||||
unless klass.class == Module
|
||||
%w(ping).each do |x|
|
||||
klass.install_have_child_element("#{TRACKBACK_PREFIX}_#{x}")
|
||||
end
|
||||
|
||||
%w(about).each do |x|
|
||||
klass.install_have_children_element("#{TRACKBACK_PREFIX}_#{x}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Ping < Element
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_prefix
|
||||
TRACKBACK_PREFIX
|
||||
end
|
||||
|
||||
def required_uri
|
||||
TRACKBACK_URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["resource", ::RSS::RDF::URI, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
def initialize(resource=nil)
|
||||
super()
|
||||
@resource = resource
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @resource
|
||||
rv = %Q!<#{TRACKBACK_PREFIX}:ping #{::RSS::RDF::PREFIX}:resource="#{h @resource}"/>!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["resource", true],
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class About < Element
|
||||
include RSS10
|
||||
|
||||
class << self
|
||||
|
||||
def required_prefix
|
||||
TRACKBACK_PREFIX
|
||||
end
|
||||
|
||||
def required_uri
|
||||
TRACKBACK_URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
[
|
||||
["resource", ::RSS::RDF::URI, true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
def initialize(resource=nil)
|
||||
super()
|
||||
@resource = resource
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @resource
|
||||
rv = %Q!<#{TRACKBACK_PREFIX}:about #{::RSS::RDF::PREFIX}:resource="#{h @resource}"/>!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def _attrs
|
||||
[
|
||||
["resource", true],
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
module TrackBackModel20
|
||||
include BaseTrackBackModel
|
||||
extend BaseModel
|
||||
|
||||
def self.append_features(klass)
|
||||
super
|
||||
|
||||
unless klass.class == Module
|
||||
%w(ping).each do |x|
|
||||
klass.install_have_child_element("#{TRACKBACK_PREFIX}_#{x}")
|
||||
end
|
||||
|
||||
%w(about).each do |x|
|
||||
klass.install_have_children_element("#{TRACKBACK_PREFIX}_#{x}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Ping < Element
|
||||
include RSS09
|
||||
|
||||
content_setup
|
||||
|
||||
class << self
|
||||
|
||||
def required_prefix
|
||||
TRACKBACK_PREFIX
|
||||
end
|
||||
|
||||
def required_uri
|
||||
TRACKBACK_URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @content
|
||||
rv = %Q!<#{TRACKBACK_PREFIX}:ping>#{h @content}</#{TRACKBACK_PREFIX}:ping>!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class About < Element
|
||||
include RSS09
|
||||
|
||||
content_setup
|
||||
|
||||
class << self
|
||||
|
||||
def required_prefix
|
||||
TRACKBACK_PREFIX
|
||||
end
|
||||
|
||||
def required_uri
|
||||
TRACKBACK_URI
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def to_s(convert=true)
|
||||
if @content
|
||||
rv = %Q!<#{TRACKBACK_PREFIX}:about>#{h @content}</#{TRACKBACK_PREFIX}:about>!
|
||||
rv = @converter.convert(rv) if convert and @converter
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
class RDF
|
||||
class Item; include TrackBackModel10; end
|
||||
end
|
||||
|
||||
class Rss
|
||||
class Channel
|
||||
class Item; include TrackBackModel20; end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
19
lib/rss/utils.rb
Normal file
19
lib/rss/utils.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
module RSS
|
||||
|
||||
module Utils
|
||||
|
||||
def get_file_and_line_from_caller(i=0)
|
||||
tmp = caller[i].split(':')
|
||||
line = tmp.pop.to_i
|
||||
file = tmp.join(':')
|
||||
[file, line]
|
||||
end
|
||||
|
||||
def html_escape(s)
|
||||
s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<")
|
||||
end
|
||||
alias h html_escape
|
||||
|
||||
end
|
||||
|
||||
end
|
69
lib/rss/xmlparser.rb
Normal file
69
lib/rss/xmlparser.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
begin
|
||||
require "xml/encoding-ja"
|
||||
rescue LoadError
|
||||
require "xmlencoding-ja"
|
||||
if defined?(Kconv)
|
||||
module XMLEncoding_ja
|
||||
class SJISHandler
|
||||
include Kconv
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module RSS
|
||||
|
||||
class XMLParser < ::XML::Parser
|
||||
|
||||
include XML::Encoding_ja
|
||||
|
||||
def listener=(listener)
|
||||
@listener = listener
|
||||
end
|
||||
|
||||
def startElement(name, attrs)
|
||||
@listener.tag_start(name, attrs)
|
||||
end
|
||||
|
||||
def endElement(name)
|
||||
@listener.tag_end(name)
|
||||
end
|
||||
|
||||
def character(data)
|
||||
@listener.text(data)
|
||||
end
|
||||
|
||||
def xmlDecl(version, encoding, standalone)
|
||||
@listener.xmldecl(version, encoding, standalone == 1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Parser < BaseParser
|
||||
|
||||
private
|
||||
def _parse
|
||||
begin
|
||||
parser = XMLParser.new
|
||||
parser.listener = @listener
|
||||
parser.parse(@rss)
|
||||
rescue XMLParserError => e
|
||||
raise NotWellFormedError.new(parser.line){e.message}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Listener < BaseListener
|
||||
|
||||
include ListenerMixin
|
||||
|
||||
def xmldecl(version, encoding, standalone)
|
||||
super
|
||||
# Encoding is converted to UTF-8 when XMLParser parses XML.
|
||||
@encoding = 'UTF-8'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
97
lib/rss/xmlscanner.rb
Normal file
97
lib/rss/xmlscanner.rb
Normal file
|
@ -0,0 +1,97 @@
|
|||
require 'xmlscan/scanner'
|
||||
|
||||
module RSS
|
||||
|
||||
class Parser < BaseParser
|
||||
|
||||
private
|
||||
def _parse
|
||||
begin
|
||||
XMLScan::XMLScanner.new(@listener).parse(@rss)
|
||||
rescue XMLScan::Error => e
|
||||
raise NotWellFormedError.new(e.lineno){e.message}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Listener < BaseListener
|
||||
|
||||
include XMLScan::Visitor
|
||||
include ListenerMixin
|
||||
|
||||
ENTITIES = {
|
||||
'lt' => '<',
|
||||
'gt' => '>',
|
||||
'amp' => '&',
|
||||
'quot' => '"',
|
||||
'apos' => '\''
|
||||
}
|
||||
|
||||
def on_xmldecl_version(str)
|
||||
@version = str
|
||||
end
|
||||
|
||||
def on_xmldecl_encoding(str)
|
||||
@encoding = str
|
||||
end
|
||||
|
||||
def on_xmldecl_standalone(str)
|
||||
@standalone = str
|
||||
end
|
||||
|
||||
def on_xmldecl_end
|
||||
xmldecl(@version, @encoding, @standalone)
|
||||
end
|
||||
|
||||
alias_method(:on_chardata, :text)
|
||||
alias_method(:on_cdata, :text)
|
||||
|
||||
def on_etag(name)
|
||||
tag_end(name)
|
||||
end
|
||||
|
||||
def on_entityref(ref)
|
||||
text(ENTITIES[ref])
|
||||
end
|
||||
|
||||
def on_charref(code)
|
||||
text([code].pack('U'))
|
||||
end
|
||||
|
||||
alias_method(:on_charref_hex, :on_charref)
|
||||
|
||||
def on_stag(name)
|
||||
@attrs = {}
|
||||
end
|
||||
|
||||
def on_attribute(name)
|
||||
@attrs[name] = @current_attr = ''
|
||||
end
|
||||
|
||||
def on_attr_value(str)
|
||||
@current_attr << str
|
||||
end
|
||||
|
||||
def on_attr_entityref(ref)
|
||||
@current_attr << ENTITIES[ref]
|
||||
end
|
||||
|
||||
def on_attr_charref(code)
|
||||
@current_attr << [code].pack('U')
|
||||
end
|
||||
|
||||
alias_method(:on_attr_charref_hex, :on_attr_charref)
|
||||
|
||||
def on_stag_end(name)
|
||||
tag_start(name, @attrs)
|
||||
end
|
||||
|
||||
def on_stag_end_empty(name)
|
||||
tag_start(name, @attrs)
|
||||
tag_end(name)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
186
sample/rss/articles.rss
Normal file
186
sample/rss/articles.rss
Normal file
|
@ -0,0 +1,186 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
|
||||
xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
|
||||
xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
|
||||
>
|
||||
|
||||
<channel rdf:about="http://slashdot.org/">
|
||||
<title>Slashdot: Articles</title>
|
||||
<link>http://slashdot.org/</link>
|
||||
<description>News for nerds, stuff that matters</description>
|
||||
<dc:language>en-us</dc:language>
|
||||
<dc:rights>Copyright &copy; 1997-2001, OSDN</dc:rights>
|
||||
<dc:date>2003-03-16T06:13:51+00:00</dc:date>
|
||||
<dc:publisher>OSDN</dc:publisher>
|
||||
<dc:creator>pater@slashdot.org</dc:creator>
|
||||
<dc:subject>Technology</dc:subject>
|
||||
<syn:updatePeriod>hourly</syn:updatePeriod>
|
||||
<syn:updateFrequency>1</syn:updateFrequency>
|
||||
<syn:updateBase>1970-01-01T00:00+00:00</syn:updateBase>
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/16/0414225" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/16/0131253" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/15/2233217" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/15/2059226" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/15/1734207" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/15/1711213" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/15/162202" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/15/147223" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/15/0237232" />
|
||||
<rdf:li rdf:resource="http://slashdot.org/article.pl?sid=03/03/15/1328203" />
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
<image rdf:resource="http://images.slashdot.org/topics/topicslashdot.gif" />
|
||||
<textinput rdf:resource="http://slashdot.org/search.pl" />
|
||||
</channel>
|
||||
|
||||
<image rdf:about="http://images.slashdot.org/topics/topicslashdot.gif">
|
||||
<title>Slashdot: Articles</title>
|
||||
<url>http://images.slashdot.org/topics/topicslashdot.gif</url>
|
||||
<link>http://slashdot.org/</link>
|
||||
</image>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/16/0414225">
|
||||
<title>Live Vorbis Streams Over 802.11b From SXSW.com</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/16/0414225</link>
|
||||
<description>chupacabra writes "SXSW.com in Austin, Texas has a group of computers in various music venues around town. The ices/icecast stream is sent over 802.11 to a ...</description>
|
||||
<dc:creator>timothy</dc:creator>
|
||||
<dc:subject>wireless</dc:subject>
|
||||
<dc:date>2003-03-16T04:19:46+00:00</dc:date>
|
||||
<slash:department>decent-exposure</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>50</slash:comments>
|
||||
<slash:hitparade>50,43,33,18,10,4,1</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/16/0131253">
|
||||
<title>Music Companies Bemoan New High-Cap Portables</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/16/0131253</link>
|
||||
<description>An anonymous reader writes "New Scientist reports: 'The music industry this week condemned the launch of two recording systems that will let people copy ...</description>
|
||||
<dc:creator>timothy</dc:creator>
|
||||
<dc:subject>hardware</dc:subject>
|
||||
<dc:date>2003-03-16T02:09:34+00:00</dc:date>
|
||||
<slash:department>that's-a-lot-of-lake-woebegone-days</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>184</slash:comments>
|
||||
<slash:hitparade>184,170,134,89,41,27,23</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/15/2233217">
|
||||
<title>New Social-Network Mapping Tools Compared</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/15/2233217</link>
|
||||
<description>Roland Piquepaille writes "There are many new visualization tools around us which try to map our social networks. In this column, I examined Inflow, a ...</description>
|
||||
<dc:creator>timothy</dc:creator>
|
||||
<dc:subject>software</dc:subject>
|
||||
<dc:date>2003-03-15T23:16:26+00:00</dc:date>
|
||||
<slash:department>useful-in-high-school-sex-ed-class</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>65</slash:comments>
|
||||
<slash:hitparade>65,62,48,32,14,11,8</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/15/2059226">
|
||||
<title>AMD Opteron Due In April</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/15/2059226</link>
|
||||
<description>updog writes "Here's an article from Infoworld claiming that the new 64-bit AMD Opteron is ready to launch on April 22. Some of the notable features of the new ...</description>
|
||||
<dc:creator>timothy</dc:creator>
|
||||
<dc:subject>amd</dc:subject>
|
||||
<dc:date>2003-03-15T21:07:45+00:00</dc:date>
|
||||
<slash:department>grain-of-salt-please</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>244</slash:comments>
|
||||
<slash:hitparade>244,227,174,119,38,22,18</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/15/1734207">
|
||||
<title>Clear Case Roundup</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/15/1734207</link>
|
||||
<description>The Cheat writes "Interested in making your computer the envy of all the other computers on the block? What visitors to oooh and ahhh when they enter your ...</description>
|
||||
<dc:creator>CowboyNeal</dc:creator>
|
||||
<dc:subject>hardware</dc:subject>
|
||||
<dc:date>2003-03-15T19:48:26+00:00</dc:date>
|
||||
<slash:department>classy-chassis</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>169</slash:comments>
|
||||
<slash:hitparade>169,163,115,68,29,18,14</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/15/1711213">
|
||||
<title>Forbes on Lessig and Eldred</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/15/1711213</link>
|
||||
<description>scubacuda writes "In the Forbes editorial, Fact and Comment , Steve Forbes voices his support for Lessig and the Eldred case: 'Maybe Congress should just be ...</description>
|
||||
<dc:creator>timothy</dc:creator>
|
||||
<dc:subject>money</dc:subject>
|
||||
<dc:date>2003-03-15T18:40:21+00:00</dc:date>
|
||||
<slash:department>capitalist-tool</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>189</slash:comments>
|
||||
<slash:hitparade>189,183,158,115,44,30,19</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/15/162202">
|
||||
<title>Modular Home Network PVR at CeBIT</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/15/162202</link>
|
||||
<description>Mackus Daddius writes "This ought to give the MPAA a conniption: 'The Lancaster system is modular, consisting of a TV tuner (analogue or digital), a hard disk ...</description>
|
||||
<dc:creator>CowboyNeal</dc:creator>
|
||||
<dc:subject>tv</dc:subject>
|
||||
<dc:date>2003-03-15T17:37:55+00:00</dc:date>
|
||||
<slash:department>different-kinds-of-tv-networks</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>75</slash:comments>
|
||||
<slash:hitparade>75,63,49,34,12,9,8</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/15/147223">
|
||||
<title>EA, Eidos Have No Plans for Xbox Live</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/15/147223</link>
|
||||
<description>News for nerds writes "Eidos, maker of Tomb Raider, said it doesn't plan to make games for Xbox Live because Microsoft controls the system and manages ...</description>
|
||||
<dc:creator>CowboyNeal</dc:creator>
|
||||
<dc:subject>games</dc:subject>
|
||||
<dc:date>2003-03-15T15:24:48+00:00</dc:date>
|
||||
<slash:department>getting-connected</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>275</slash:comments>
|
||||
<slash:hitparade>275,266,192,109,45,26,17</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/15/0237232">
|
||||
<title>Build Your Own Sherman Tank</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/15/0237232</link>
|
||||
<description>absolut.evil writes "OK, so admittedly it is only 1/5th scale, but still pretty cool.. especially if you're a kid. The thing comes complete with working ...</description>
|
||||
<dc:creator>Hemos</dc:creator>
|
||||
<dc:subject>toys</dc:subject>
|
||||
<dc:date>2003-03-15T14:36:49+00:00</dc:date>
|
||||
<slash:department>constructing-the-universe</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>216</slash:comments>
|
||||
<slash:hitparade>216,206,122,70,36,21,16</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.org/article.pl?sid=03/03/15/1328203">
|
||||
<title>Sony's Cashless Smart Card Catching on in Japan</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/15/1328203</link>
|
||||
<description>Spasemunki writes "The New York Times reports here on the success in Japan of an RF-based, cash replacement smart card developed by Sony. Used primarily by ...</description>
|
||||
<dc:creator>timothy</dc:creator>
|
||||
<dc:subject>money</dc:subject>
|
||||
<dc:date>2003-03-15T13:36:32+00:00</dc:date>
|
||||
<slash:department>are-they-tradeable</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>196</slash:comments>
|
||||
<slash:hitparade>196,192,152,77,27,15,10</slash:hitparade>
|
||||
</item>
|
||||
|
||||
<textinput rdf:about="http://slashdot.org/search.pl">
|
||||
<title>Search Slashdot</title>
|
||||
<description>Search Slashdot stories</description>
|
||||
<name>query</name>
|
||||
<link>http://slashdot.org/search.pl</link>
|
||||
</textinput>
|
||||
|
||||
</rdf:RDF>
|
28
sample/rss/content.xml
Normal file
28
sample/rss/content.xml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
>
|
||||
|
||||
<channel rdf:about="http://example.org/rss.rdf">
|
||||
<title>Example Feed</title>
|
||||
<link>http://www.example.org</link>
|
||||
<description>Simply for the purpose of demonstration.</description>
|
||||
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<rdf:li resource="http://example.org/item/" />
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
|
||||
</channel>
|
||||
|
||||
<item rdf:about="http://example.org/item/">
|
||||
<title>The Example Item</title>
|
||||
<link>http://example.org/item/</link>
|
||||
<content:encoded><![CDATA[<p>What a <em>beautiful</em> day!</p>]]></content:encoded>
|
||||
</item>
|
||||
</rdf:RDF>
|
||||
|
186
sample/rss/index.rdf.ja
Normal file
186
sample/rss/index.rdf.ja
Normal file
|
@ -0,0 +1,186 @@
|
|||
<?xml version='1.0' encoding='EUC-JP'?>
|
||||
<rdf:RDF
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<channel rdf:about='http://bat/~gallery'>
|
||||
<title>トップ</title>
|
||||
|
||||
<link>http://bat/~gallery</link>
|
||||
|
||||
<description>ギャラリートップ</description>
|
||||
|
||||
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<rdf:li resource="http://bat/~gallery/./momi/paris/%A5%D5%A5%E9%A5%F3%A5%B9%20%20%A5%D1%A5%EA.jpg" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./momi/paris/invalides.jpg" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./momi/paris/tour%2Deffel2.jpg" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./momi/paris/tour%2Deffel3.jpg" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./momi/paris/france_photo2_055.jpg" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./momi/paris/france_photo2_054.jpg" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./momi/paris/tour%2Deffel.jpg" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./wrudgef/SPANGLETRASH/101%2D0133_IMG.JPG" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./wrudgef/SPANGLETRASH/101%2D0137_IMG.JPG" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./wrudgef/SPANGLETRASH/101%2D0136_IMG.JPG" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./wrudgef/SPANGLETRASH/101%2D0134_IMG.JPG" />
|
||||
|
||||
<rdf:li resource="http://bat/~gallery/./wrudgef/BARROWGANG/100%2D0099_IMG.JPG" />
|
||||
|
||||
|
||||
|
||||
</rdf:Seq>
|
||||
|
||||
|
||||
</items>
|
||||
|
||||
|
||||
|
||||
</channel>
|
||||
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./momi/paris/%A5%D5%A5%E9%A5%F3%A5%B9%20%20%A5%D1%A5%EA.jpg'>
|
||||
<title>フランス パリ</title>
|
||||
|
||||
|
||||
<description></description>
|
||||
|
||||
<dc:date>2003-06-11T00:13:33+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./momi/paris/invalides.jpg'>
|
||||
<title>金ぴかドーム</title>
|
||||
|
||||
|
||||
<description>アンヴァリッドといいます。軍事博物館・解放勲章博物館・サン=ルイ教会、そして、あのナポレオン1世の墓としての顔も持っています。</description>
|
||||
|
||||
<dc:date>2003-06-11T00:13:33+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./momi/paris/tour%2Deffel2.jpg'>
|
||||
<title>下から激写</title>
|
||||
|
||||
|
||||
<description>エッフェルを下から見るとこんな感じです。</description>
|
||||
|
||||
<dc:date>2003-06-11T00:13:33+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./momi/paris/tour%2Deffel3.jpg'>
|
||||
<title>今度は上から</title>
|
||||
|
||||
|
||||
<description>エッフェル塔は、1階・2階に登ることができます。これは1階からのショット。地上30m位でしょうか。パリが一望できます。</description>
|
||||
|
||||
<dc:date>2003-06-11T00:13:33+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./momi/paris/france_photo2_055.jpg'>
|
||||
<title>どこだかわかりますか?</title>
|
||||
|
||||
|
||||
<description>シャンゼリゼと言えばわかりますよね。
|
||||
この画像じゃただの道ですが・・・</description>
|
||||
|
||||
<dc:date>2003-06-11T00:13:33+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./momi/paris/france_photo2_054.jpg'>
|
||||
<title>凱旋門のようです</title>
|
||||
|
||||
|
||||
<description>メッカですからねぇ。足下はロータリーです。よくぶつからないものだと感心してしまいます。</description>
|
||||
|
||||
<dc:date>2003-06-11T00:13:33+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./momi/paris/tour%2Deffel.jpg'>
|
||||
<title>エッフェル塔というやつです</title>
|
||||
|
||||
|
||||
<description>天気悪くて綺麗じゃないですね。できた当時は、鉄の塊にかなり批判的な声が多かったらしいですよ。今は観光名所ですけどね。</description>
|
||||
|
||||
<dc:date>2003-06-11T00:13:33+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./wrudgef/SPANGLETRASH/101%2D0133_IMG.JPG'>
|
||||
<title>プリント半そでシャツ</title>
|
||||
|
||||
|
||||
<description>¥9.800 M <ピンク ブルー クロ>
|
||||
背中にト音記号プリントの入ったシャツ。
|
||||
Tシャツやタンクトップの上に羽織ってロックに決めよう!</description>
|
||||
|
||||
<dc:date>2003-06-11T00:12:36+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./wrudgef/SPANGLETRASH/101%2D0137_IMG.JPG'>
|
||||
<title>髑髏プリント半そでシャツ</title>
|
||||
|
||||
|
||||
<description>¥9.800 M <ボルドー グレイ クロ>
|
||||
スパングルお得意のハードな髑髏プリントのシャツ。
|
||||
背中が主張しまくります。</description>
|
||||
|
||||
<dc:date>2003-06-11T00:12:36+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./wrudgef/SPANGLETRASH/101%2D0136_IMG.JPG'>
|
||||
<title>髑髏プリント半そでシャツ</title>
|
||||
|
||||
|
||||
<description>¥9.800 M <ボルドー グレイ クロ>
|
||||
スパングルお得意のハードな髑髏プリントのシャツ。
|
||||
背中が主張しまくります。</description>
|
||||
|
||||
<dc:date>2003-06-11T00:12:36+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./wrudgef/SPANGLETRASH/101%2D0134_IMG.JPG'>
|
||||
<title>プリント半そでシャツ</title>
|
||||
|
||||
|
||||
<description>¥9.800 M <ピンク ブルー クロ>
|
||||
背中にト音記号プリントの入ったシャツ。
|
||||
Tシャツやタンクトップの上に羽織ってロックに決めよう!</description>
|
||||
|
||||
<dc:date>2003-06-11T00:12:36+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
<item rdf:about='http://bat/~gallery/./wrudgef/BARROWGANG/100%2D0099_IMG.JPG'>
|
||||
<title>あみあみスカート</title>
|
||||
|
||||
|
||||
<description>¥8.900 フリーサイズ <ベージュ>
|
||||
綿であんだニットなので軽い印象です。
|
||||
ちょうどひざ上丈なので、パンツと重ねたりもできます。</description>
|
||||
|
||||
<dc:date>2003-06-11T00:09:25+09:00</dc:date>
|
||||
|
||||
</item>
|
||||
|
||||
|
||||
|
||||
|
||||
</rdf:RDF>
|
84
sample/rss/list_description.rb
Normal file
84
sample/rss/list_description.rb
Normal file
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require "nkf"
|
||||
class String
|
||||
# From tdiary.rb
|
||||
def shorten( len = 120 )
|
||||
lines = NKF::nkf( "-e -m0 -f#{len}", self.gsub( /\n/, ' ' ) ).split( /\n/ )
|
||||
lines[0].concat( '...' ) if lines[0] and lines[1]
|
||||
lines[0]
|
||||
end
|
||||
end
|
||||
|
||||
require "rss/parser"
|
||||
require "rss/1.0"
|
||||
require "rss/2.0"
|
||||
require "rss/dublincore"
|
||||
|
||||
channels = {}
|
||||
verbose = false
|
||||
|
||||
def error(exception)
|
||||
mark = "=" * 20
|
||||
mark = "#{mark} error #{mark}"
|
||||
puts mark
|
||||
puts exception.class
|
||||
puts exception.message
|
||||
puts exception.backtrace
|
||||
puts mark
|
||||
end
|
||||
|
||||
before_time = Time.now
|
||||
ARGV.each do |fname|
|
||||
if fname == '-v'
|
||||
verbose = true
|
||||
next
|
||||
end
|
||||
rss = nil
|
||||
f = File.new(fname).read
|
||||
begin
|
||||
## do validate parse
|
||||
rss = RSS::Parser.parse(f)
|
||||
rescue RSS::InvalidRSSError
|
||||
error($!) if verbose
|
||||
## do non validate parse for invalid RSS 1.0
|
||||
begin
|
||||
rss = RSS::Parser.parse(f, false)
|
||||
rescue RSS::Error
|
||||
## invalid RSS.
|
||||
error($!) if verbose
|
||||
end
|
||||
rescue RSS::Error
|
||||
error($!) if verbose
|
||||
end
|
||||
if rss.nil?
|
||||
puts "#{fname} does not include RSS 1.0 or 0.9x/2.0"
|
||||
else
|
||||
begin
|
||||
rss.output_encoding = "euc-jp"
|
||||
rescue RSS::UnknownConversionMethodError
|
||||
error($!) if verbose
|
||||
end
|
||||
rss.channel.title ||= "Unknown"
|
||||
rss.items.each do |item|
|
||||
item.title ||= "Unknown"
|
||||
channels[rss.channel.title] ||= []
|
||||
channels[rss.channel.title] << item if item.description
|
||||
end
|
||||
end
|
||||
end
|
||||
processing_time = Time.now - before_time
|
||||
|
||||
channels.sort do |x, y|
|
||||
x[0] <=> y[0]
|
||||
end[0..20].each do |title, items|
|
||||
puts "Channel : #{title}" unless items.empty?
|
||||
items.sort do |x, y|
|
||||
x.title <=> y.title
|
||||
end[0..10].each do |item|
|
||||
puts " Item : #{item.title.shorten(50)}"
|
||||
puts " Description : #{item.description.shorten(50)}"
|
||||
end
|
||||
end
|
||||
|
||||
puts "Processing Time : #{processing_time}s"
|
170
sample/rss/news.rss
Normal file
170
sample/rss/news.rss
Normal file
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
>
|
||||
<channel rdf:about="http://www.php.net/">
|
||||
<title>PHP: Hypertext Preprocessor</title>
|
||||
<link>http://www.php.net/</link>
|
||||
<description>The PHP scripting language web site</description>
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<rdf:li rdf:resource="http://www.phparch.com" />
|
||||
<rdf:li rdf:resource="http://www.php.net/echo" />
|
||||
<rdf:li rdf:resource="http://phpconf.hu/" />
|
||||
<rdf:li rdf:resource="http://www.php.net/release_4_3_1.php" />
|
||||
<rdf:li rdf:resource="http://www.php-con.com/return.php?i=ph2" />
|
||||
<rdf:li rdf:resource="http://www.linuxtag.org/2003/en/conferences/cfp.html" />
|
||||
<rdf:li rdf:resource="http://phpconf.phpquebec.org/index.php" />
|
||||
<rdf:li rdf:resource="http://www.phpconference.com/" />
|
||||
<rdf:li rdf:resource="http://pear.php.net/" />
|
||||
<rdf:li rdf:resource="http://www.derickrethans.nl/20021230.php" />
|
||||
<rdf:li rdf:resource="http://www.php.net/downloads.php" />
|
||||
<rdf:li rdf:resource="http://weblabor.hu/php-doc-chm" />
|
||||
<rdf:li rdf:resource="http://www.mysql.com/events/uc2003/" />
|
||||
<rdf:li rdf:resource="http://www.php.net/news.rss" />
|
||||
<rdf:li rdf:resource="http://www.afup.org/" />
|
||||
<rdf:li rdf:resource="http://www.phpmag.de/" />
|
||||
<rdf:li rdf:resource="http://www.phparch.com/" />
|
||||
<rdf:li rdf:resource="http://www.php.net/urlhowto.php" />
|
||||
<rdf:li rdf:resource="http://www.linuxworldexpo.de" />
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
</channel>
|
||||
<!-- RSS-Items -->
|
||||
|
||||
<item rdf:about="http://www.phparch.com">
|
||||
<title>Grant Program</title>
|
||||
<link>http://www.phparch.com</link>
|
||||
<description> php|architect, is proud to announce the creation of the php|architect Grant Program, whose goal is to provide financial support to best-of-breed PHP-related projects. Participation in the program is open to all open-source projects that are related to PHP (but not necessarily written in PHP). The program is accepting submissions now and will start distributing grants in June of 2003. For more information, visit the program's website. </description>
|
||||
<dc:date>2003-03-06</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.php.net/echo">
|
||||
<title>Set your own language preference</title>
|
||||
<link>http://www.php.net/echo</link>
|
||||
<description> Starting from today, your browser's "Accept Language" setting is also honored on language sensitive pages on the php.net site. If you would like to get to the documentation page of echo for example, you can use the /echo shortcut on all mirror sites, if your browser is set to provide your language preference information to the server. This also makes the PHP error message links point to the documentation in your preferred language. You can set your preferences under Edit/Preferences/Navigator/Languages in Mozilla, and under Tools/Internet Options/Languages in Internet Explorer. This will probably also enhance your web experience on sites providing translated content. </description>
|
||||
<dc:date>2003-03-01</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://phpconf.hu/">
|
||||
<title>First Hungarian PHP Conference</title>
|
||||
<link>http://phpconf.hu/</link>
|
||||
<description> The members of the Hungarian PHP community announce the first Hungarian PHP Conference which will take place in Budapest, on Saturday March 29th, sponsored by several international and local companies. The conference offers an entirely free one day activity with several presentations addressing basic and advanced topics, as well, exclusively in Hungarian. Moreover, a five kilobyte-limited PHP contest has been started to discover the most talented PHP programmers in our country. The programme includes the first session of the so-called PHP Division which will be established with the set purpose of representing the community itself and promoting their interests in any national business and official phorums. </description>
|
||||
<dc:date>2003-02-25</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.php.net/release_4_3_1.php">
|
||||
<title>PHP 4.3.1 released in response to CGI vulnerability</title>
|
||||
<link>http://www.php.net/release_4_3_1.php</link>
|
||||
<description> The PHP Group today announced the details of a serious CGI vulnerability in PHP version 4.3.0. A security update, PHP 4.3.1, fixes the issue. Everyone running affected version of PHP (as CGI) are encouraged to upgrade immediately. The new 4.3.1 release does not include any other changes, so upgrading from 4.3.0 is safe and painless. </description>
|
||||
<dc:date>2003-02-17</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.php-con.com/return.php?i=ph2">
|
||||
<title>PHPCon East 2003 - (April 23-25, 2003)</title>
|
||||
<link>http://www.php-con.com/return.php?i=ph2</link>
|
||||
<description> PHPCon announces PHPCon East 2003 in New York City. This conference features two days of technical learning with speakers such as Rasmus Lerdorf, Zeev Suraski, Michael Radwin, George Schlossnagle and Jeremy Zawodny. PHPCon East also adds a third, full day of tutorials offering practical, cogent PHP solutions and ideas including: MySQL and PHP; Building and Consuming Web Services with SOAP; Getting Started with PHP; High Performance PHP: Profiling and Benchmarking; and more PHPCon East has discounts for early registration, students, non-profits, and Tutorial/Conference packages. Early Bird Deadline is March 31st. For more program information, visit the PHPCon website. </description>
|
||||
<dc:date>2003-02-01</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.linuxtag.org/2003/en/conferences/cfp.html">
|
||||
<title>LinuxTag, Karlsruhe, July 10th - 13th</title>
|
||||
<link>http://www.linuxtag.org/2003/en/conferences/cfp.html</link>
|
||||
<description> LinuxTag e.V has once again put out a call for papers for this years conference event. Submit your ideas and proposals here. This year's theme looks at discussions that promote new ideas, delivers a broad overview, introduces new users to linux, or discusses the legal, moral and other implications of linux and free software. </description>
|
||||
<dc:date>2002-12-30</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://phpconf.phpquebec.org/index.php">
|
||||
<title>Conf&eacute;rence PHP Qu&eacute;bec 2003 - (Montr&eacute;al, March 20&amp;21rst, 2003)</title>
|
||||
<link>http://phpconf.phpquebec.org/index.php</link>
|
||||
<description> The PHP Qu&eacute;bec association announces the Conf&eacute;rence PHP Qu&eacute;bec 2003. The conference will take place in the &Eacute;cole Polytechnique de Montr&eacute;al, Qu&eacute;bec, Canada. The Conf&eacute;rence PHP Qu&eacute;bec features two days of conferences, with outstanding customer cases from Canada, and cutting edge technical sessions, hosted by international experts. An exhibitor room will showroom professional solutions. Learn more about those exciting days at phpconf.phpquebec.com. </description>
|
||||
<dc:date>2003-01-28</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.phpconference.com/">
|
||||
<title>International PHP Conference 2003 - Spring Edition (Amsterdam, May 8-9)</title>
|
||||
<link>http://www.phpconference.com/</link>
|
||||
<description> Software &amp; Support Verlag announced the International PHP Conference 2003 - Spring Edition - in Amsterdam. The dates for this event for PHP enthusiasts from all over the world will be May 8 and 9, 2003. The conference venue is the RAI conference center in Amsterdam. Like the International PHP Conferences in Frankfurt this conference will offer a first class program to an international audience of PHP enthusiasts. We are happy to ask you to submit your proposals for the session program. The topics are General PHP, PHP &amp; Business, PHP &amp; Databases, PHP Design, PHP Extensions, PHP &amp; XML and PHP-GTK. </description>
|
||||
<dc:date>2003-01-13</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://pear.php.net/">
|
||||
<title>PEAR Out of Beta!</title>
|
||||
<link>http://pear.php.net/</link>
|
||||
<description> The PEAR development team is proud to announce that PEAR is finally out of its long beta period. As of PHP 4.3, the PEAR installer is installed by default. Unix support is considered stable, while Windows and Darwin are still of beta-quality. </description>
|
||||
<dc:date>2003-01-11</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.derickrethans.nl/20021230.php">
|
||||
<title>PHP Look Back 2002</title>
|
||||
<link>http://www.derickrethans.nl/20021230.php</link>
|
||||
<description> We are at the end of 2002, and it seemed appropriate to look back on the development issues of the past year. So starts the first PHP Look Back You can find it in on the non-official personal website of one of the PHP Developers here. Happy New Year </description>
|
||||
<dc:date>2002-12-31</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.php.net/downloads.php">
|
||||
<title>PHP 4.3.0 Released!</title>
|
||||
<link>http://www.php.net/downloads.php</link>
|
||||
<description> The PHP developers are pleased to announce the immediate availability of PHP 4.3.0, the latest and greatest version of this extremely popular and widely used scripting language. This release contains a multitude of changes, bug fixes and improvements over the previous one, PHP 4.2.3. It further elevates PHP's standing as a serious contender in the general purpose scripting language arena. Please see the full release announcement. </description>
|
||||
<dc:date>2002-12-27</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://weblabor.hu/php-doc-chm">
|
||||
<title>New Release of the PHP Manual CHM Edition - Please Help Us</title>
|
||||
<link>http://weblabor.hu/php-doc-chm</link>
|
||||
<description> The 11th sample of the CHM edition is available for download from today. The sample hopefully fixed the missing page bugs forever, introduces a new integration method (see documentation inside) and contains actual manual text, mirrors list and user notes. See the edition's page for download. We also would like to ask you to help out in testing our new on-the-fly syntax highlighter, which would make the CHM significantly smaller, and would give you more options in displaying the pages. See the edition's page for more information. </description>
|
||||
<dc:date>2002-12-27</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.mysql.com/events/uc2003/">
|
||||
<title>MySQL Users Conference and Expo 2003 in San Jose</title>
|
||||
<link>http://www.mysql.com/events/uc2003/</link>
|
||||
<description> MySQL AB is proud to host the world's First Annual MySQL User Conference, to be held in the heart of Silicon Valley, April 10-12, 2003. This event promises to be the biggest gathering of MySQL database users ever in one location. Designed for both the MySQL developer and the corporate decision maker, this is the place to learn about the latest in MySQL technology, discover new business opportunities, take a pulse on industry direction and commune with like minds. More information on the event's website. </description>
|
||||
<dc:date>2002-12-16</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.php.net/news.rss">
|
||||
<title>PHP news feed available</title>
|
||||
<link>http://www.php.net/news.rss</link>
|
||||
<description> The news of PHP.net is available now in RSS 1.0 format via our new news.rss file. You can add this file to any news reader or portal site to get the latest official PHP news. We strongly recommend you to cache the contents locally on your side, as the newsfeed is updated daily. The RSS file is available on every mirror site. </description>
|
||||
<dc:date>2002-12-01</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.afup.org/">
|
||||
<title>Forum PHP 2002 in Paris, France</title>
|
||||
<link>http://www.afup.org/</link>
|
||||
<description> The French PHP User Group AFUP invites you to the "Forum PHP 2002" in Paris, on December 9th and 10th. Designed to meet the needs of PHP aware companies and all the French PHP developper's community alike, this event will provided you with valuable and up-to-date information. For more information (in French) see the PHP Forum website. </description>
|
||||
<dc:date>2002-11-21</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.phpmag.de/">
|
||||
<title>PHP Magazine - International Edition</title>
|
||||
<link>http://www.phpmag.de/</link>
|
||||
<description> Software &amp; Support Verlag GmbH is going to publish an International version of the PHP Magazin. This magazine was initiated after growing interest for an English magazine after the German version has been around for a few months. PHP Magazine not only informs about the scripting language itself, but also about related technologies such as the Apache Web Server, database technologies, XML and other innovative internet technologies. Different sections within the magazine are oriented towards the specific question areas with which a web developer is confronted in daily practice. The first issue will be published in December and the frequency of issues is two months. You will be able to subscribe on the website which will open shortly. </description>
|
||||
<dc:date>2002-11-17</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.phparch.com/">
|
||||
<title>New Monthly PHP Magazine Launched</title>
|
||||
<link>http://www.phparch.com/</link>
|
||||
<description> php|architect, a new monthly magazine dedicated exclusively to PHP, has launched its website. php|a is published in PDF format and is available worldwide. It covers a variety of advanced topics ranging from day-to-day programming to the internals of PHP. A sample article on the creation of a web-based PDF converter is also available on the magazine website </description>
|
||||
<dc:date>2002-11-15</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.php.net/urlhowto.php">
|
||||
<title>PHP Search Bars available for major browsers</title>
|
||||
<link>http://www.php.net/urlhowto.php</link>
|
||||
<description> We added a new option to access our site's content quickly. In addition to URL shortcuts, keyboard shortcuts and browser specific magic you can now use our Search Bar from the major browsers. Please help us to test this new service, and provide feedback via the bug system (categorize your bug as a PHP.net website bug please). </description>
|
||||
<dc:date>2002-10-29</dc:date>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://www.linuxworldexpo.de">
|
||||
<title>PHP at the LinuxWorld Expo Oct. 29-31th in Frankfurt, Germany</title>
|
||||
<link>http://www.linuxworldexpo.de</link>
|
||||
<description> For the first time the Open Source projects comprising the popular LAMP platform (Linux, Apache, MySQL and PHP) will be present at the LinuxWorld Expo with its own booth. At the booth, which is organized by the German PHP Association and the PHP Usergroup Frankfurt, fair visitors can experience and learn about Apache, MySQL, PHP and related projects. Visitors can take LAMP home, too, since there will be a CD with the necessary software available at the booth. </description>
|
||||
<dc:date>2002-10-28</dc:date>
|
||||
</item>
|
||||
<!-- / RSS-Items PHP/RSS -->
|
||||
</rdf:RDF>
|
235
sample/rss/php.rss
Normal file
235
sample/rss/php.rss
Normal file
|
@ -0,0 +1,235 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rdf:RDF
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
|
||||
xml:lang="ja">
|
||||
|
||||
<channel rdf:about="http://ishinao.net/WikiLike/?sort=modified_desc">
|
||||
<title>ishinao's personal WikiLike</title>
|
||||
<link>http://ishinao.net/WikiLike/?sort=modified_desc</link>
|
||||
<description>WikiLike Modified List</description>
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=276" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=275" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=274" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=273" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=271" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=272" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=270" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=243" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=269" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=268" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=267" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=266" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=265" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=264" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=263" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=262" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=261" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=260" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=258" />
|
||||
<rdf:li rdf:resource="http://ishinao.net/WikiLike/?sid=1" />
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
</channel>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=276">
|
||||
<title>プログラミング言語の制御構造系命令一覧</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=276</link>
|
||||
<description>すぐに混乱して分からなくなるいろいろな[[プログラミング言語]]の[[制御構造]]系[[命令]]の一覧。たぶん第1稿にはいろいろ間違いがありそう&言語の選択も適当だな。あとで細かく直そう。変なところを見つけたら教えてください。
|
||||
|
||||
!![[Perl]]
|
||||
!!!for
|
||||
for ($i=0; $i<10; $i++) {
|
||||
}
|
||||
!!!while
|
||||
while ($i<10) {
|
||||
break; //脱出
|
||||
next; //次ループ
|
||||
}
|
||||
!!!foreach array
|
||||
</description>
|
||||
<dc:date>2003-03-03T08:51:55+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/276</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=275">
|
||||
<title>IMを次のレベルに――MSの「3°」が目指す世界 from ZDNet</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=275</link>
|
||||
<description>*[[IM]]を次のレベルに――[[MS]]の「[[3°]]」が目指す世界 - http://www.zdnet.co.jp/news/0303/03/xert_msim.html
|
||||
|
||||
[[マイクロソフト]]は、企業向けの[[P2P]]アプリは[[Groove]]で、一般向けのP2PアプリはThreeDegreeで、って感じの戦略なのかな。あまりにもリッチなアプリになりすぎて動作が重くなりすぎなければ、結構人気が出そうだ。ただ、グループ内でのインターネット越しの[[音楽共有]]ってのが本当にOKならば、</description>
|
||||
<dc:date>2003-03-03T08:11:56+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/275</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=274">
|
||||
<title>音楽業界に喝を入れる「DVDミュージック」の正体 from ZDNet</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=274</link>
|
||||
<description>*[[音楽]]業界に喝を入れる「[[DVDミュージック]]」の正体 - http://www.zdnet.co.jp/news/0303/03/cjad_kodera3.html
|
||||
|
||||
「[[DVD-R]]とかに適当に[[オーディオ]]とか[[静止画]]とかのデータを入れて、DVDが再生できる装置でそれなりに再生できるようにする」ことに「DVDミュージック」という[[規格]]名を付けて売り出してみよう、ってことか。
|
||||
|
||||
はっきりいって、[[DVD-Audio]]みたいな[[次世代]]高級音楽メディア規格</description>
|
||||
<dc:date>2003-03-03T08:07:09+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/274</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=273">
|
||||
<title>ネットワーク攻撃への反撃は合法か from ZDNet</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=273</link>
|
||||
<description>*[[ネットワーク]][[攻撃]]への[[反撃]]は[[合法]]か - http://www.zdnet.co.jp/news/0303/01/nebt_09.html
|
||||
|
||||
>この条項の下で被害者は、攻撃を加えている[[サーバ]]がたとえ他人のものであっても、そのサーバ内の攻撃用プログラムを停止させることが許されると解釈できるという。
|
||||
|
||||
確かに限定された反撃ならば良さそうな気がするけれども、[[過剰防衛]]との境目が難しそうな気もする。もしもこれが認められるならば、[[ウイルス駆除]]ソフトメーカ</description>
|
||||
<dc:date>2003-03-03T03:54:43+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/273</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=271">
|
||||
<title>言葉交差点</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=271</link>
|
||||
<description>*言葉交差点 - http://ishinao.net/wordslinks/
|
||||
|
||||
[[キーワード]]で複数の[[Webサイト]]を結びつける[[リンク集]]。[[プロジェクト名]]を「[[言葉交差点]]」とつけて[[テスト]]中。いろいろなやり方がありすぎて、どれが一番いいのかわからなくなったので、とても[[プリミティブ]]なもので雰囲気を見定めてみよう。特に[[インターフェース]]周りの扱いが難しい。ひとまずWikiLikeからは[[自動登録]]ができるようにTrackBack的なやり方を実装してみ</description>
|
||||
<dc:date>2003-03-03T02:53:20+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/271</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=272">
|
||||
<title>複製症候群</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=272</link>
|
||||
<description>[[講談社文庫]] [[西澤保彦]]著 「[[複製症候群:http://www.amazon.co.jp/exec/obidos/ASIN/4062734575/ishinao-22]]」
|
||||
|
||||
ある日突然空から不思議な巨大[[チューブ]]が現れた。それに触った生き物はすべて完全な[[複製]]([[コピー]])が作られてしまう。家族や友人、教師、そして兄に対して強いコンプレックスをもつ“僕”は、友人達とともにチューブの中に閉じこめられてしまった……。
|
||||
|
||||
という[[SF]]的シチュエーションにおける[[</description>
|
||||
<dc:date>2003-03-02T14:36:12+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/272</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=270">
|
||||
<title>バラのツボミ</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=270</link>
|
||||
<description>[[20030302131001.jpg:http://ishinao.net/image/20030302131001.jpg]]
|
||||
まだこの時期のツボミは切らなきゃダメらしいね。でも切るに忍びない。</description>
|
||||
<dc:date>2003-03-02T04:10:02+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/270</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=243">
|
||||
<title>Apacheのユーザーが変わった</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=243</link>
|
||||
<description>昨日[[特に使うあてのないWiki]]の更新ができなくなっているとコメントで教えられて見に行ったら、なぜかPukiWikiからデータファイルを更新できなくなっていた。なぜだろうと調べてみたら、[[Apache]]の[[動作ユーザー]](ID)が変わっている。そのせいで、旧ユーザー権限で作成されたファイルへのWriteアクセスができなくなっていた。
|
||||
|
||||
Read権限はあったんで、いったんFTPでバックアップを取り、データディレクトリを別に差し替えて606で放り込んだら動くようになったけれども、旧データディ</description>
|
||||
<dc:date>2003-03-01T19:06:25+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/243</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=269">
|
||||
<title>椎名林檎CCCD</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=269</link>
|
||||
<description>あら、新しい[[椎名林檎]]の[[アルバム]]って[[CCCD]]だったのね。危なく買うところだったよ。ってのは別にCCCDに絶対反対原理主義者だからではなく(おおむね反対+あんなしょぼい技術使うなんてバカじゃねーのとは思っているけど)、俺は基本的に[[PC]]+[[シリコンオーディオプレイヤー]]で[[音楽]]を聴く人間なんで、CCCDじゃあ買う意味がないから。もちろんCCCDにしたってのは、そういう人は私の音楽を聴くなって意味なんだよね。</description>
|
||||
<dc:date>2003-03-01T07:28:43+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/269</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=268">
|
||||
<title>◆「ルパン三世」がハリウッドで実写映画化 from ZAKZAK</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=268</link>
|
||||
<description>*◆「[[ルパン三世]]」がハリウッドで実写映画化 - http://www.zakzak.co.jp/midnight/hollywood/backnumber/L/030228-L.html
|
||||
|
||||
[[アメリカン]]な[[ハリウッド]]加工された[[ルパン]]三世。見たいような見たくないような。見ていないけど駄作と評判だった[[ハドソン・ホーク]]とか思い浮かべちゃうしな。できの悪い[[007]]シリーズみたいなものになりそうな気もするし。</description>
|
||||
<dc:date>2003-03-01T06:49:20+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/268</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=267">
|
||||
<title>パフォーマンスは良好も、依然ぬぐえぬ不安――「Centrinoテクノロジ」プレス向け事前セミナー開催 from ZDNet</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=267</link>
|
||||
<description>*パフォーマンスは良好も、依然ぬぐえぬ不安――「[[Centrino]]テクノロジ」プレス向け事前セミナー開催 - http://www.zdnet.co.jp/news/0302/28/nj00_centrino.html
|
||||
|
||||
技術・性能的には優れているけれども、営業・広告・タイミング的には問題がたくさんありますってことか。それにしても[[インテル]]って、こんなにわかりやすい例示(タクシーを使ったモデル)満載の[[プレス]]向けの[[セミナー]]なんてやるタイプだっけ? もうちょっと普通に技術説明っ</description>
|
||||
<dc:date>2003-03-01T06:46:37+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/267</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=266">
|
||||
<title>◆「中川家」弟、キレて路上ナンパ女性殴る from ZAKZAK</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=266</link>
|
||||
<description>*◆「[[中川家]]」弟、キレて路上ナンパ女性殴る - http://www.zakzak.co.jp/top/top0301_1_08.html
|
||||
|
||||
[[漫才師]]に[[ツッコミ]]を入れられたくらいで訴えるなんて冗談の分からないやつだなー。という論調にはならないんですね。「女性の頭を1回殴った」ってのが具体的にどのレベルなのかよく分からないけど。</description>
|
||||
<dc:date>2003-03-01T06:33:53+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/266</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=265">
|
||||
<title>工学部・水柿助教授の日常</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=265</link>
|
||||
<description>[[GENTOSHA NOVELS]] [[森博嗣]]著 「[[工学部・水柿助教授の日常:http://www.amazon.co.jp/exec/obidos/ASIN/4344009088/ishinao-22]]」
|
||||
|
||||
しまった、だまされた。新しい[[ミステリー]]小説かと思ったら、そういう体裁を取った[[エッセイ]]じゃねーか。それなりに面白かったし、そうだと知っていてもたぶん買ったとは思うけれども(でも今まで基本的に森博嗣のエッセイ系はあんまり買っていない)、期待したものが得られなかったという</description>
|
||||
<dc:date>2003-03-01T05:20:40+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/265</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=264">
|
||||
<title>瞬間移動死体</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=264</link>
|
||||
<description>[[講談社文庫]] [[西澤保彦]]著 「[[瞬間移動死体:http://www.amazon.co.jp/exec/obidos/ASIN/4062732262/ishinao-22]]」
|
||||
|
||||
とても限定された[[テレポーテーション]]能力を持つ男が、それを利用した[[殺人]]を計画する。という西澤保彦得意の[[SF]]ネタを使った[[ミステリー]]。面白くなかったわけではないけれども、なんかちょっといまいちな印象。ああいう枠の設定だったら、ほかにもいろいろな選択肢(それなりに理屈が通るストーリー)が</description>
|
||||
<dc:date>2003-03-01T05:12:07+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/264</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=263">
|
||||
<title>犯罪系ファンタジー</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=263</link>
|
||||
<description>*[[性犯罪]] - http://www.ag.wakwak.com/~mai_u/umui/200302c.html#200302281232
|
||||
*[[フェティシズム]](というのも変な感じがしますけれども) - http://darkares.tdiary.net/20030228.html#p02
|
||||
*Re:性犯罪 - http://www.ag.wakwak.com/~mai_u/umui/200302c.html#200302281858
|
||||
*してはいけないからこそ - http://dark</description>
|
||||
<dc:date>2003-03-01T03:06:59+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/263</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=262">
|
||||
<title>携帯からのメール投稿に対応</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=262</link>
|
||||
<description>というわけで、[[携帯]]からの[[メール]][[投稿]]に対応してみたわけです。一応[[添付ファイル]]にも対応。ただし今のところ[[JPEG]]のみ展開。
|
||||
|
||||
私は[[au]]ユーザーなんで[[動画]]は[[ezmovie]]という妙な[[フォーマット]]なんですよね。[[CODEC]]自体は[[mpeg4]]なんだけど、[[コンテナフォーマット]]がau独自の変な形式なんで、普通のPCじゃあ[[再生]]できない。一応[[Windows]]用の[[プレイヤー]]ソフトは配布されているけど、あんなのa</description>
|
||||
<dc:date>2003-02-28T13:11:07+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/262</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=261">
|
||||
<title>カエルのマウスパッド</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=261</link>
|
||||
<description>[[20030228215401:http://ishinao.net/image/20030228215401.jpg]]
|
||||
ぺらぺらの布製マウスパッドは持ち運びに便利。</description>
|
||||
<dc:date>2003-02-28T12:54:01+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/261</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=260">
|
||||
<title>携帯からの投稿テスト</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=260</link>
|
||||
<description>[[20030228212001:http://ishinao.net/image/20030228212001.jpg]]
|
||||
テストメールだよ。写っているのはFOMAの色もの端末。それにしても携帯で長文は打ちたくないよね。</description>
|
||||
<dc:date>2003-02-28T12:32:06+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/260</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=258">
|
||||
<title>私は、サイボーグ from ZDNet</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=258</link>
|
||||
<description>*私は、[[サイボーグ]] - http://www.zdnet.co.jp/news/0302/28/nj00_interaction.html
|
||||
|
||||
>神経と接続された[[義手]]。そのイメージは、[[平井和正]]の『[[死霊狩り]]』に出てきた。宇宙生命体[[ゾンビー]]と戦うために戦闘訓練を受けた主人公の田村俊夫が、訓練の最中に左手を失うのである。
|
||||
|
||||
えーっと、ほかに適当な例はなかったんだっけ? コブラはちょっと違うか。なんかたくさんありそうなのに思いつかないなー。っつーか、「死霊狩り」をナ</description>
|
||||
<dc:date>2003-02-28T11:57:19+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/258</trackback:ping>
|
||||
</item>
|
||||
<item rdf:about="http://ishinao.net/WikiLike/?sid=1">
|
||||
<title>FrontPage</title>
|
||||
<link>http://ishinao.net/WikiLike/?sid=1</link>
|
||||
<description>ここは、[[ishinao]]専用のWikiLikeです。ページの投稿・編集はishinaoしか出来ません。コメントの投稿は誰でも可能です。
|
||||
|
||||
*[[すべて:http://ishinao.net/WikiLike/view.php]]
|
||||
*[[日常:http://ishinao.net/WikiLike/view.php?query=%C6%FC%BE%EF]]
|
||||
*[[WebWatch:http://ishinao.net/WikiLike/view.php?query=WebWatch]]
|
||||
*[</description>
|
||||
<dc:date>2003-02-28T09:35:59+00:00</dc:date>
|
||||
<trackback:ping>http://ishinao.net/WikiLike/tb.php/1</trackback:ping>
|
||||
</item>
|
||||
</rdf:RDF>
|
59
sample/rss/raa-rdf10.xml
Normal file
59
sample/rss/raa-rdf10.xml
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://my.netscape.com/rdf/simple/0.9/">
|
||||
|
||||
<channel>
|
||||
<title>Ruby App. Archive</title>
|
||||
<link>http://raa.ruby-lang.org/</link>
|
||||
<description>New 10 files in the Ruby Application Archive</description>
|
||||
</channel>
|
||||
<item>
|
||||
<title>library: classes to manage versioned libraries</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=library</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>sys-host: hostname and ip address info via Ruby - C extension</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=sys-host</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>sys-uptime: 'uptime' information via Ruby - C extension</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=sys-uptime</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>hail_ruby: most of the ruby stuff from Hail packaged as an extension</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=hail_ruby</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>tiki: Tiki - WikiEngine</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=tiki</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>sys-cpu: Interface for cpu information</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=sys-cpu</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>btpgsql: Bi-Temporal PostgreSQL - manage data which changes over time</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=btpgsql</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>ynot2day_server: YNot2Day Server Templator</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=ynot2day_server</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>kwarts: kwa's Ruby Template System - a very fast template system</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=kwarts</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>exerb-win32: Exerb for Windows</title>
|
||||
<link>http://raa.ruby-lang.org/list.rhtml?name=exerb-win32</link>
|
||||
</item>
|
||||
</rdf:RDF>
|
44
sample/rss/rnn.rdf
Normal file
44
sample/rss/rnn.rdf
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/">
|
||||
<channel>
|
||||
<title>RNN</title><link>http://rnn.sourceforge.jp</link><description>Ruby no News</description>
|
||||
<items><rdf:Seq>
|
||||
<rdf:li rdf:resource="http://rnn.sourceforge.jp/modules/news/article.php?storyid=140"/>
|
||||
<rdf:li rdf:resource="http://rnn.sourceforge.jp/modules/news/article.php?storyid=139"/>
|
||||
<rdf:li rdf:resource="http://rnn.sourceforge.jp/modules/news/article.php?storyid=138"/>
|
||||
<rdf:li rdf:resource="http://rnn.sourceforge.jp/modules/news/article.php?storyid=137"/>
|
||||
<rdf:li rdf:resource="http://rnn.sourceforge.jp/modules/news/article.php?storyid=136"/>
|
||||
</rdf:Seq></items>
|
||||
</channel>
|
||||
|
||||
|
||||
<item rdf:about="http://rnn.sourceforge.jp/modules/news/article.php?storyid=140">
|
||||
<title>まつもとさんへのインタビュー</title>
|
||||
<link>http://rnn.sourceforge.jp/modules/news/article.php?storyid=140</link>
|
||||
<description>まつもとさんへのインタビュー (Fri Mar 14 16:40:43 JST 2003)</description>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://rnn.sourceforge.jp/modules/news/article.php?storyid=139">
|
||||
<title>kwarts -- HTMLテンプレートライブラリ</title>
|
||||
<link>http://rnn.sourceforge.jp/modules/news/article.php?storyid=139</link>
|
||||
<description>kwarts -- HTMLテンプレートライブラリ (Wed Mar 12 22:14:54 JST 2003)</description>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://rnn.sourceforge.jp/modules/news/article.php?storyid=138">
|
||||
<title>Linux Jurnal: Ruby</title>
|
||||
<link>http://rnn.sourceforge.jp/modules/news/article.php?storyid=138</link>
|
||||
<description>Linux Jurnal: Ruby (Wed Mar 12 04:02:01 JST 2003)</description>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://rnn.sourceforge.jp/modules/news/article.php?storyid=137">
|
||||
<title>電脳 Ruby セミナー</title>
|
||||
<link>http://rnn.sourceforge.jp/modules/news/article.php?storyid=137</link>
|
||||
<description>電脳 Ruby セミナー (Tue Mar 11 20:20:37 JST 2003)</description>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://rnn.sourceforge.jp/modules/news/article.php?storyid=136">
|
||||
<title>KWICツールtea</title>
|
||||
<link>http://rnn.sourceforge.jp/modules/news/article.php?storyid=136</link>
|
||||
<description>KWICツールtea (Tue Mar 11 01:01:19 JST 2003)</description>
|
||||
</item>
|
||||
</rdf:RDF>
|
87
sample/rss/rss.xml
Normal file
87
sample/rss/rss.xml
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>@IT Insider.NETフォーラム</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/</link>
|
||||
<description>ITエンジニア向けWebサイト@IT内の、Microsoft .NET ソリューションのための技術情報サイトフォーラム</description>
|
||||
<language>ja-jp</language>
|
||||
<copyright>Copyright (c) 2000-2003, atmarkIT Corporation</copyright>
|
||||
<pubDate>Mon, 26 May 2003 03:00:01 +0900</pubDate>
|
||||
<image>
|
||||
<url>http://www.atmarkit.co.jp/aboutus/copyright/atit_links.gif</url>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/</link>
|
||||
</image>
|
||||
<item>
|
||||
<title>.NET TIPS - .NET開発のテクニックとヒント集 -</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/dotnettips/index/index.html</link>
|
||||
<description>確実な終了処理を行うには?ピクセルの色をHTMLカラーへ変換するには?文字列を連結するには?</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>プログラマを.NETに誘うVS.NET 2003のラインアップ</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/insiderseye/20030522vs2003/vs2003.html</link>
|
||||
<description> .NET Frameworkを搭載したWindowsサーバとともに、Visual Studio .NETの新版がいよいよ発売となる。.NETソリューションの普及は加速されるのか?</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>認証によるWebサービス・クライアントの識別</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/hybooks/vbnet01/vbnet01_01.html</link>
|
||||
<description>XML WebサービスをASP.NET+VB.NETで構築する際に利用可能なセキュリティ制御について詳細に解説していく</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Visual Studio .NET 2003は“買い”か?</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/questionnaire/2003-04/2003_04.html</link>
|
||||
<description>VS.NET 2003が間もなく発売となるが、これに先立ちアンケート調査を行った。現在の開発環境と2003の導入予定は? 魅力となる新機能は?</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>ASP.NETにおける認証と認定</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/aspnet/aspnet17/aspnet17_01.html</link>
|
||||
<description>Webアプリのセキュリティ確保は非常に面倒な問題だが、ASP.NETには数少ない手順でこれを実現するための仕組みが用意されている</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>.NETデータ・プロバイダによるデータベースのアクセス</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/basics/adonet02/adonet02_01.html</link>
|
||||
<description>ADO.NETによるデータベース・プログラミングをマスターするためには、まず「.NETデータ・プロバイダ」をよく理解しておくことが重要だ</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>VS.NETでプログラム・レス開発を学ぶ(前編)</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/aspandvs/aspandvs02/aspandvs02_01.html</link>
|
||||
<description> VS.NETの統合開発環境が可能にする、プログラム・レスなASP.NETアプリケーション開発を簡単なサンプルで実体験</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>あなたのコードは(再び)生き残れるか</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/terrarium2/terrarium01/terrarium01_01.html</link>
|
||||
<description> プログラマの注目を集めたテラリウム・コンテストが今年も開催される。システムのバージョンアップにともない、前回の記事を加筆・修正</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>.NET TIPS - .NET開発のテクニックとヒント集 -</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/dotnettips/index/index.html</link>
|
||||
<description>Win32 APIやDLL関数を呼び出すには?
|
||||
Win32 APIやDLL関数に文字列バッファを渡すには?
|
||||
Win32 APIやDLL関数に構造体を渡すには?</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>DOM(Document Object Model)でXML文書を扱う</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/easyxml/easyxml04/easyxml04_01.html</link>
|
||||
<description> XML文書に含まれる情報をツリー構造に展開し、データへのランダム・アクセスや編集を可能にするDOMを用いて、.NETでXML文書を操作する</description>
|
||||
<category>Insider.NET</category>
|
||||
<pubDate>Sat, 30 Nov 2002 00:00:00 +0900</pubDate>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
203
sample/rss/rss2dc.xml
Normal file
203
sample/rss/rss2dc.xml
Normal file
|
@ -0,0 +1,203 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<rdf:RDF
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:sy="http://purl.org/rss/modules/syndication/"
|
||||
xml:lang="ja">
|
||||
<channel rdf:about="http://www.atmarkit.co.jp">
|
||||
<title>@IT</title>
|
||||
<link>http://www.atmarkit.co.jp</link>
|
||||
<description>ITエンジニア対象の技術解説情報&コミュニティサイト</description>
|
||||
<language>ja</language>
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fdotnet/dotnettips/index/index.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fxml/survey/survey09/xml09.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fjava/rensai2/jspservlet05/jspsevlet05_1.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fbiz/column/fl/reg117/01.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fsys/zunouhoudan/036zunou/emb_security.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fjava/devs/dstylefaq/uml/index/dstylefaquml_index.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fwin2k/verification/vpn03/vpn03_01.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fdotnet/insiderseye/20030522vs2003/vs2003.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fbiz/data/index.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fsecurity/rensai/unix_sec01/unix_sec01.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/flinux/rensai/linuxtips/tipsindex.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fwin2k/insiderseye/20030519ws2003an/ws2003an.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fdotnet/hybooks/vbnet01/vbnet01_01.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fnetwork/trend/20030405/sip.html" />
|
||||
<rdf:li rdf:resource="http://www.atmarkit.co.jp/fbiz/bookreview/itroi/index.html" />
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
</channel>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fdotnet/dotnettips/index/index.html">
|
||||
<title>.NET TIPS - .NET開発のテクニックとヒント集 -</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/dotnettips/index/index.html</link>
|
||||
<description>確実な終了処理を行うには?
|
||||
ピクセルの色をHTMLカラーへ変換するには?
|
||||
文字列を連結するには?</description>
|
||||
<category>Insider.NET</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-23T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fxml/survey/survey09/xml09.html">
|
||||
<title>読者のXMLとWebサービスの活用状況は?</title>
|
||||
<link>http://www.atmarkit.co.jp/fxml/survey/survey09/xml09.html</link>
|
||||
<description>2年半前の調査と比べてXMLの利用率は倍以上に。一方で現状はWebサービスを利用する予定がない、という読者の理由も明らかに</description>
|
||||
<category>XML & Web Services</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-23T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fjava/rensai2/jspservlet05/jspsevlet05_1.html">
|
||||
<title>JSPの基本「暗黙オブジェクト」を使う</title>
|
||||
<link>http://www.atmarkit.co.jp/fjava/rensai2/jspservlet05/jspsevlet05_1.html</link>
|
||||
<description>暗黙オブジェクトはWebプログラミングになくてならない機能を集約しています。今回から2回に分けてその使い方を理解します</description>
|
||||
<category>Java Solution</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
山田祥寛
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-23T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fbiz/column/fl/reg117/01.html">
|
||||
<title>新しいネット広告モデル「PPCSE」が開く未来</title>
|
||||
<link>http://www.atmarkit.co.jp/fbiz/column/fl/reg117/01.html</link>
|
||||
<description> ひん死のインターネット広告業界に現れた救世主「PPC検索エンジン」。“広告”と“インターネット”はどのように“両立”するのか</description>
|
||||
<category>Business Computing</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-23T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fsys/zunouhoudan/036zunou/emb_security.html">
|
||||
<title>組み込み用途でもセキュリティが大注目?</title>
|
||||
<link>http://www.atmarkit.co.jp/fsys/zunouhoudan/036zunou/emb_security.html</link>
|
||||
<description> SuicaやETCに代表されるような組み込み分野では認証が必須。こうした用途では、どのようにセキュリティを確保しているのだろうか?</description>
|
||||
<category>System Insider</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
Massa POP Izumida
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-22T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fjava/devs/dstylefaq/uml/index/dstylefaquml_index.html">
|
||||
<title>Q)UMLの9種類のダイアグラムとは?</title>
|
||||
<link>http://www.atmarkit.co.jp/fjava/devs/dstylefaq/uml/index/dstylefaquml_index.html</link>
|
||||
<description>9種類のUMLダイアグラムがオブジェクト指向開発の各工程でどのような役割を果たすのか。ダイアグラムの基本を詳細に解説する</description>
|
||||
<category>Java Solution</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
羽生田栄一
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-22T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fwin2k/verification/vpn03/vpn03_01.html">
|
||||
<title>PPTPサーバの構築</title>
|
||||
<link>http://www.atmarkit.co.jp/fwin2k/verification/vpn03/vpn03_01.html</link>
|
||||
<description> 今回からは実際にVPN環境を構築してみる。まずはActive Directoryドメインの導入とPPTPによるVPNサーバの導入方法について解説する</description>
|
||||
<category>Windows Server Insider</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
デジタルアドバンテージ
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-22T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fdotnet/insiderseye/20030522vs2003/vs2003.html">
|
||||
<title>プログラマを.NETに誘うVS.NET 2003のラインアップ</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/insiderseye/20030522vs2003/vs2003.html</link>
|
||||
<description> .NET Frameworkを搭載したWindowsサーバとともに、Visual Studio .NETの新版がいよいよ発売となる。.NETソリューションの普及は加速されるのか?</description>
|
||||
<category>Insider.NET</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
デジタルアドバンテージ
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-22T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fbiz/data/index.html">
|
||||
<title>Business & IT DataLinks(IT業界データ集)</title>
|
||||
<link>http://www.atmarkit.co.jp/fbiz/data/index.html</link>
|
||||
<description>−「ソリューション・サービス市場動向調査」<br>−「不正アクセス行為対策の実態調査」<br>など、5月10日までのデータを12件追加</description>
|
||||
<category>Business Computing</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-22T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fsecurity/rensai/unix_sec01/unix_sec01.html">
|
||||
<title>不要なサービスの停止こそ管理の第一歩</title>
|
||||
<link>http://www.atmarkit.co.jp/fsecurity/rensai/unix_sec01/unix_sec01.html</link>
|
||||
<description> 悩ましいのは停止できないサーバの管理。稼働サービスの停止を最小限に抑えた、セキュリティ向上の設定やツールを紹介</description>
|
||||
<category>Security&Trust</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-22T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/flinux/rensai/linuxtips/tipsindex.html">
|
||||
<title>Linux Tips</title>
|
||||
<link>http://www.atmarkit.co.jp/flinux/rensai/linuxtips/tipsindex.html</link>
|
||||
<description>Red Hat LinuxでAPTを使うには
|
||||
sshでパスワードなしにログインするには
|
||||
Unicodeのテキストファイルをほかの文字コードに変換</description>
|
||||
<category>Linux Square</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-22T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fwin2k/insiderseye/20030519ws2003an/ws2003an.html">
|
||||
<title>Windows Server 2003日本語版がいよいよ登場</title>
|
||||
<link>http://www.atmarkit.co.jp/fwin2k/insiderseye/20030519ws2003an/ws2003an.html</link>
|
||||
<description> 次世代サーバ「Windows Server 2003」、最新開発環境、64bit対応のSQL
|
||||
Serverが同日発表。.NET戦略は加速されるのか?</description>
|
||||
<category>Windows Server Insider</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
デジタルアドバンテージ
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-21T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fdotnet/hybooks/vbnet01/vbnet01_01.html">
|
||||
<title>認証によるWebサービス・クライアントの識別</title>
|
||||
<link>http://www.atmarkit.co.jp/fdotnet/hybooks/vbnet01/vbnet01_01.html</link>
|
||||
<description>XML WebサービスをASP.NET+VB.NETで構築する際に利用可能なセキュリティ制御について詳細に解説していく</description>
|
||||
<category>Insider.NET</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-21T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fnetwork/trend/20030405/sip.html">
|
||||
<title>SIP:マイクロソフトがIP電話を面白くする!?</title>
|
||||
<link>http://www.atmarkit.co.jp/fnetwork/trend/20030405/sip.html</link>
|
||||
<description> IP網と電話網を統合させるVoIPの、基盤技術の1つ「SIP」。 MSの新サーバでも対応が始まった、この音声や画像などを扱うプロトコルはなぜ重要なのか</description>
|
||||
<category>Master of IP Network</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
鈴木淳也
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-21T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.atmarkit.co.jp/fbiz/bookreview/itroi/index.html">
|
||||
<title>正しいIT投資を目指すための5冊</title>
|
||||
<link>http://www.atmarkit.co.jp/fbiz/bookreview/itroi/index.html</link>
|
||||
<description> 特集「いまから始めるIT投資効果測定」連動企画。いままさにITのROI測定へ取り組もうという方、具体策がわからず悩んでいる方にオススメの5冊を紹介</description>
|
||||
<category>Business Computing</category>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:creator>
|
||||
|
||||
</dc:creator>
|
||||
<dc:date>2003-05-21T00:00:00+09:00</dc:date>
|
||||
</item>
|
||||
</rdf:RDF>
|
271
sample/rss/rssMarkPilgrimExample.xml
Normal file
271
sample/rss/rssMarkPilgrimExample.xml
Normal file
|
@ -0,0 +1,271 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rss version="2.0"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
|
||||
xmlns:admin="http://webns.net/mvcb/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/">
|
||||
|
||||
<channel>
|
||||
<title>dive into mark</title>
|
||||
<link>http://diveintomark.org/</link>
|
||||
<description>A lot of effort went into making this effortless.</description>
|
||||
<dc:language>en-us</dc:language>
|
||||
<dc:creator>f8dy@diveintomark.org</dc:creator>
|
||||
<dc:rights>Copyright 2002</dc:rights>
|
||||
<dc:date>2002-09-29T23:40:06-05:00</dc:date>
|
||||
<admin:generatorAgent rdf:resource="http://www.movabletype.org/?v=2.21" />
|
||||
<admin:errorReportsTo rdf:resource="mailto:f8dy@diveintomark.org"/>
|
||||
<sy:updatePeriod>hourly</sy:updatePeriod>
|
||||
<sy:updateFrequency>1</sy:updateFrequency>
|
||||
<sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Dooce</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/29.html#dooce</link>
|
||||
<description>Reborn.</description>
|
||||
<guid isPermaLink="false">1856@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><a href="http://www.dooce.com/">Reborn</a>.</p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-29T23:40:06-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Advanced CSS lists</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/27.html#advanced_css_lists</link>
|
||||
<description>Mark Newhouse: CSS Design: Taming Lists. "I'll demonstrate how to use CSS to bring unwieldy lists under control. It's time for you to tell lists how to behave, instead of letting them run wild on your web page."</description>
|
||||
<guid isPermaLink="false">1855@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><cite title="A List Apart">Mark Newhouse</cite>: <a href="http://www.alistapart.com/stories/taminglists/">CSS Design: Taming Lists</a>. <q>I'll demonstrate how to use CSS to bring unwieldy lists under control. It's time for you to tell lists how to behave, instead of letting them run wild on your web page.</q></p>]]></content:encoded>
|
||||
<dc:subject>CSS</dc:subject>
|
||||
<dc:date>2002-09-27T23:22:56-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Pingback vs. Trackback</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/27.html#pingback_vs_trackback</link>
|
||||
<description>Ian Hickson: Whitepaper: Pingback vs Trackback. "It seems pingback has caused quite a stir in the Web logging and syndication communities."</description>
|
||||
<guid isPermaLink="false">1854@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><cite>Ian Hickson</cite>: <a href="http://ln.hixie.ch/?start=1033171507&count=1">Whitepaper: Pingback vs Trackback</a>. <q>It seems pingback has caused quite a stir in the Web logging and syndication communities! The spec is barely a week old and already I'm seeing pingbacks on sites of people I've never heard of, so implementations are spreading, which is great. It also seems pingback has acted a little like a kick in the backside to the trackback folk, causing them to work on the transparency side of trackback, which is good to see too.</q></p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-27T23:17:51-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Introduction</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/27.html#introduction</link>
|
||||
<description>Jeffrey Zeldman: "Welcome to zeldman.com, a poorly designed website that hides vital content from its many naive, first-time visitors.</description>
|
||||
<guid isPermaLink="false">1853@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><cite>Jeffrey Zeldman</cite>: <q><a href="http://www.zeldman.com/daily/0902b.html#medesignprettyoneday">Welcome to zeldman.com</a>, a poorly designed website that hides vital content from its many naive, first-time visitors.</q></p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-27T18:16:54-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>It's Google's world, we just live in it</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/27.html#its_googles_world_we_just_live_in_it</link>
|
||||
<description>Results of a Google search for "It's so-and-so's world, we just live in it".</description>
|
||||
<guid isPermaLink="false">1851@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p>A Google search for <a href="http://www.google.com/search?q=%22world+we+just+live+in+it%22">"world we just live in it"</a> reveals that:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://www.cinepad.com/sinatra/sinatra.htm">It's Frank [Sinatra]'s world, we just live in it</a></li>
|
||||
<li><a href="http://www.poopoochoochoo.com/">It's Mandy's world, we just live in it</a></li>
|
||||
<li><a href="http://members.tripod.com/~cshel/elijah.html">It's Elijah [Jordan Wood]'s world, we just live in it</a></li>
|
||||
<li><a href="http://jerseybeat1.homestead.com/files/52601.html">It's 'N Sync's world, we just live in it</a></li>
|
||||
<li><a href="http://www.vh1.com/artists/news/1444632/06202001/aerosmith.jhtml">It's Aerosmith's world, we just live in it</a></li>
|
||||
<li><a href="http://www.biennaleofsydney.com.au/vidprog.asp#14">It's Jim's world, we just live in it</a></li>
|
||||
<li><a href="http://members.tripod.com/ddraven/psh/">It's Philip [Seymour Hoffman]'s world, we just live in it</a></li>
|
||||
<li><a href="http://espn.go.com/page2/s/wiley/001108.html">It's Jeet's [Derek Sanderson Jeter's] world, we just live in it</a></li>
|
||||
<li><a href="http://www.bcr.com/bcrmag/1998/11/p06.asp">It's the ILECs' world, we just live in it</a></li>
|
||||
<li><a href="http://www.business2.com/articles/mag/0,1640,37760,FF.html">It's Walmart's world, we just live in it</a></li>
|
||||
<li><a href="http://www.geocities.com/waltripworld/">It's Mikey's [Michael Waltrip's] world, we just live in it</a></li>
|
||||
<li><a href="http://www.angelfire.com/geek/BiancaBrandt/index.html">It's Bianca [Brandt]'s world, we just live in it</a></li>
|
||||
<li><a href="http://www.curtsandoval.com/family.htm">It's Tulip's world, we just live in it</a></li>
|
||||
<li><a href="http://www.chaseclub.com/news23.htm">It's Bill Gates' world, we just live in it</a></li>
|
||||
<li><a href="http://www.cnet.com/software/0-3227883-8-7614087-6.html">It's Microsoft's world, we just live in it</a></li>
|
||||
<li><a href="http://www.linux-mag.com/1999-05/linus_01.html">It's Linus [Torvalds]' world, we just live in it</a></li>
|
||||
<li><a href="http://www.geocities.com/michellebranchsworld/home.html">It's Michelle Branch's world, we just live in it</a></li>
|
||||
<li><a href="http://www.popmatters.com/music/reviews/g/guidedbyvoices-universal.shtml">It's Robert Pollard's world, we just live in it</a></li>
|
||||
<li><a href="http://www.theprimeone.com/archives/000067.html">It's Anna and Grace's world, we just live in it</a></li>
|
||||
<li><a href="http://www.salon.com/ent/tv/mill/1999/03/08mill.html">It's Mulder and Scully's world, we just live in it</a></li>
|
||||
<li><a href="http://www.brunching.com/gladiator.html">It's Russell Crowe's world, we just live in it</a></li>
|
||||
<li><a href="http://www.epinions.com/mvie-review-5B0-D8DF92D-38791117-prod1">It's Fellini's world, we just live in it</a></li>
|
||||
<li><a href="http://hometown.aol.com/radarama1/">It's Cairo's world, we just live in it</a></li>
|
||||
</ul>
|
||||
|
||||
<p>And finally:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://www.snopes.com/weddings/embarras/bothered.htm">It's the Bothered Bride [or Groom]'s world, we just live in it</a></li>
|
||||
</ul>
|
||||
|
||||
<p></p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-27T15:43:02-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Semantic mapping of RSS elements</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/27.html#semantic_mapping_of_rss_elements</link>
|
||||
<description>Sam Ruby has started a discussion of mapping core RSS elements to namespace-based equivalents.</description>
|
||||
<guid isPermaLink="false">1850@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p>Sam Ruby has started a discussion of <a href="http://groups.yahoo.com/group/rss-dev/message/4124">mapping core RSS elements to namespace-based equivalents</a>. This is useful for developers who want to consume RSS 2.0 feeds and want to know how to handle the new namespace-based elements. Already support <code>language</code>? Be on the lookout for <code>dc:language</code> as well. And so forth. The mapping isn't always that direct (some elements use different formats, like <code>pubDate</code> and <code>dc:date</code>), but it's a good start to an important discussion.</p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-27T13:40:34-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Repair</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/27.html#repair</link>
|
||||
<description>Kevin Guilfoile: The Half-Assed Handyman.</description>
|
||||
<guid isPermaLink="false">1849@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><cite title="The Morning News">Kevin Guilfoile</cite>: <a href="http://www.themorningnews.org/archives/stories/the_halfassed_handyman.shtml">The Half-Assed Handyman</a>. <q>Once the Half-Assed Handyman decides on a course of repair he must remain committed to it by fixing the broken object the same way over and over, even though the method is clearly ineffective, or even nonsensical.</q></p>]]></content:encoded>
|
||||
<dc:subject>Writers</dc:subject>
|
||||
<dc:date>2002-09-27T13:30:01-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Rescued pictures</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/27.html#rescued_pictures</link>
|
||||
<description>18 rescued pictures, from 1920, 1983, 1990, 2000, and 2001.</description>
|
||||
<guid isPermaLink="false">1848@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><a href="http://diveintomark.org/pictures/rescued_pictures/">18 rescued pictures</a>, from 1920, 1983, 1990, 2000, and 2001.</p>]]></content:encoded>
|
||||
<dc:subject>Personal</dc:subject>
|
||||
<dc:date>2002-09-27T01:23:29-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Chicks dig that</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/27.html#chicks_dig_that</link>
|
||||
<description>Slashdot: 37 Operating Systems, 1 PC.</description>
|
||||
<guid isPermaLink="false">1846@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><a href="http://www.maximumpc.com/features/feature_2002-09-24.html">One PC, Six Hard Drives, 37 OSes</a>! [via Slashdot: <a href="http://slashdot.org/article.pl?sid=02/09/26/1225200&mode=nested&tid=99&threshold=3">37 Operating Systems, 1 PC</a>]</p>
|
||||
|
||||
<blockquote>
|
||||
<p>Q: Were there any OSes you couldn't find?</p>
|
||||
<p>A: I couldn't find an OS that would tell me how to successfully deal with girls.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><a href="http://diveintomark.org/pictures/christmas_2001/86.html">Mac OS X, baby</a>. <a href="http://diveintomark.org/pictures/christmas_2001/87.html">Mac OS X</a>.</p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-27T01:12:29-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>RSS 2.0 template</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/26.html#rss_20_template</link>
|
||||
<description>RSS 2.0 template for Movable Type, ready to copy and paste over your existing RSS 0.91 template (index.xml). There are several design decisions at work in this tempate that bear explaining.</description>
|
||||
<guid isPermaLink="false">1844@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><a href="http://diveintomark.org/public/rss2.tmpl">RSS 2.0 template for Movable Type</a>, ready to copy and paste over your existing RSS 0.91 template (<code>index.xml</code>). No modifications are required, unless your weblog is in a language other than English, in which case you'll need to change the <code>dc:language</code> tag to <a href="http://www.loc.gov/standards/iso639-2/englangn.html">your language code</a>. (Use the 2-letter language code, unless there isn't one for your language, in which case, use the 3-letter language code. And while you're at it, put the same language code <a href="http://diveintoaccessibility.org/day_7_identifying_your_language.html">in your <code>HTML</code> tag</a> in your normal page templates. But I digress.)</p>
|
||||
|
||||
<p><a href="http://diveintomark.org/xml/rss2.xml">Here's what the RSS 2.0 output looks like</a>.</p>
|
||||
|
||||
<p>There are several design decisions at work in this template that bear explaining. First of all, this template is designed to be backward-compatible with all existing aggregators, news readers, and RSS parsers, ranging from the super-smart XML parser built into .NET to the dumb, minimal, regular-expression-based parser that your downstairs neighbor banged out on a Friday night. If you upgrade your existing <code>index.xml</code> right now, none of these parsers should crash, and none of your subscribers should scream bloody murder. This is a good thing.</p>
|
||||
|
||||
<p>Now then, if you look at the template, you'll notice a whole slew of lines at the top like <code>xmlns:dc="..."</code>. These are namespaces. Keven Hemenway has written an excellent primer on <a href="http://www.disobey.com/detergent/2002/extendingrss2/">extending RSS 2.0 with namespaces</a>, so I won't explain them here except to say that we use them, and you should get used to seeing them. Most RSS 2.0 documents you see will use namespaces in some way, because they are the primary way of adding functionality beyond the basic title-link-description combination. If all you want is title-link-description, stick with your existing RSS 0.91 template and stop reading now.</p>
|
||||
|
||||
<p>Still here? OK. Now, the <a href="http://backend.userland.com/rss">RSS 2.0 specification</a> says nothing about how to actually use namespaces in RSS, just that you're allowed to. So where did these particular namespaces come from? Well, I didn't make them up. They have been developed over the past two years by some smart people, most of whom hang out on the <a href="http://groups.yahoo.com/group/rss-dev/">RSS-DEV mailing list</a>. The namespaces were originally developed for RSS 1.0, and most of them can be used without modification in RSS 2.0. (There's a lot of stuff I'm skipping over here on purpose. There will be a lot more documentation forthcoming in the next few months on exactly how to use various namespaces in RSS 2.0. Some of it still needs to be worked out, but most of it just needs to be written down. Please be patient.)</p>
|
||||
|
||||
<p>So anyway, we use namespaces for a lot of stuff. Most stuff, in fact. In the template, you'll see title-link-description for <code>channel</code>, and title-link-description-guid for <code>item</code>. <code>guid</code> is new in RSS 2.0, and it is used to uniquely identify an item, so even if the title or description changes, aggregators know that it's the same item; the end user can choose whether to re-display changed items, but first programs need to be able to track which items are which. (<a href="http://radio.userland.com/">Radio Userland</a> already supports this.) To create the <code>guid</code>, I've combined <code>MTEntryID</code> with <code>MTBlogURL</code> to generate a unique string for each item, and I've arranged them so there's no confusion about it possibly being a URL. It's not a URL; it's just a unique string. (Other systems have stricter format requirements for guids, but RSS 2.0 does not. A guid is a unique string, and that's all.)</p>
|
||||
|
||||
<p>Pretty much everything beyond title-link-description (and guid) uses namespaces. This template makes use of all 3 of the <a href="http://purl.org/rss/1.0/modules/standard.html">standard RSS 1.0 namespaces</a>, but there are many other <a href="http://purl.org/rss/1.0/modules/proposed.html">proposed namespaces</a> that have a lot of good design behind them. We use one (<code>admin</code>), which is already widely used; the rest may be useful to you, depending on your niche. (If you think you need to design your own namespace, look through that list and make sure you're not re-inventing the wheel.)</p>
|
||||
|
||||
<p>Back to the template. Other than guid, the most important thing to note about this template is that the <code>title</code>, <code>link</code>, and <code>description</code> are all plain text. (<code>description</code> is an excerpt; if you do not enter an excerpt manually for a post, Movable Type will auto-generate one. You can control how long this auto-generated excerpt is by going to Blog Config, then Preferences, then <q>Number of words in excerpt</q>.) <code>title</code> was always supposed to be plain text, but sticking to plain text in the <code>description</code> tag is an intentional compromise, to support parsers that can not handle HTML, or handle it improperly. Never fear, the full HTML text of your post is still included; it's stored in the <code>content:encoded</code> element. (<a href="http://bitworking.org/Aggie.html">Aggie</a> already supports this.) This allows more robust news readers -- that can handle either text or HTML -- to offer the end user the choice of whether to see excerpts or full posts. Some people use news aggregators to find things to read, others like reading everything directly in their aggregator. RSS 0.9x made you (the author) choose one or the other; RSS 2.0 allows you to offer both, and pass the choice along to the end user. This is a good thing.</p>
|
||||
|
||||
<p>There's more good stuff in there, but the explanations will have to wait for another day. If you're interested in learning how to extend RSS to suit your needs, your best bet is to read through the documentation of the existing RSS 1.0 namespaces. If you have questions, your best bet is the <a href="http://groups.yahoo.com/group/rss-dev/">RSS-DEV mailing list</a>, where Kevin is currently <a href="http://groups.yahoo.com/group/rss-dev/message/4046">discussing his namespace primer</a>. Archives are public and free, so no subscription is required, and lurking is encouraged.</p>
|
||||
|
||||
<p>And watch this space.</p>]]></content:encoded>
|
||||
<dc:subject>Weblogging</dc:subject>
|
||||
<dc:date>2002-09-26T01:28:52-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>FOAF explorer</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/25.html#foaf_explorer</link>
|
||||
<description>Morten Frederiksen has taken a first stab at a real-time social network explorer based on FOAF files. It's heavy on tech details, but you can easily see the potential here.</description>
|
||||
<guid isPermaLink="false">1843@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p>Morten Frederiksen has taken a first stab at a real-time social network explorer based on FOAF files. You could <a href="http://xml.mfd-consult.dk/foaf/?foaf=http%3A%2F%2Fdiveintomark.org%2Fpublic%2Ffoaf.rdf">start on my profile</a> and explore from there, or enter the URL of your own FOAF file (at the bottom of the page). It's heavy on tech details, but you can easily see the potential here. (It's also a great way to debug your FOAF file, if you added anything manually.) Now we need somebody to build a spider that follows <code>foaf:knows</code> links and draws pretty social network diagrams, so we can see the forest for the trees.</p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-25T18:18:53-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Maps</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/25.html#maps</link>
|
||||
<description>Mark Tosczak @ Wired: A New Way to Read, Not See, Maps.</description>
|
||||
<guid isPermaLink="false">1842@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><cite title="Wired News">Mark Tosczak</cite>: <a href="http://www.wired.com/news/school/0,1383,54916,00.html">A New Way to Read, Not See, Maps</a>. <q>The map-navigation software, dubbed Blind Audio Tactile Mapping System ... takes digital map information and provides nonvisual feedback as a user moves a cursor across the map.</q></p>]]></content:encoded>
|
||||
<dc:subject>Accessibility</dc:subject>
|
||||
<dc:date>2002-09-25T10:45:15-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Plan</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/25.html#plan</link>
|
||||
<description>Paul Ford: Falling Off a Truck. "In the last 4 days I fell off a truck and was dragged for 30 feet, and was interviewed by an NPR show. Those two facts are not related except that they both happened to me and made me queasy. I also wrote a short plan outlining the rest of my life."</description>
|
||||
<guid isPermaLink="false">1841@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><cite>Paul Ford</cite>: <a href="http://ftrain.com/recent_update_etc.html">Falling Off a Truck</a>. <q>In the last 4 days I fell off a truck and was dragged for 30 feet, and was interviewed by an NPR show. Those two facts are not related except that they both happened to me and made me queasy. I also wrote a short plan outlining the rest of my life.</q></p>]]></content:encoded>
|
||||
<dc:subject>Writers</dc:subject>
|
||||
<dc:date>2002-09-25T10:43:06-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>RSS revolt</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/25.html#rss_revolt</link>
|
||||
<description>People appear to be sick of the syndication format wars. Some are protesting, some are creating new formats with new names, others are simply boycotting.</description>
|
||||
<guid isPermaLink="false">1840@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><cite>Anil Dash</cite>: <a href="http://www.dashes.com/anil/index.php?archives/003183.php">XML version 1.0</a>. <q>Why isn't there a way to syndicate my words without butchering the way they look?</q> Several people protested last week by changing their weblog templates to <a href="http://www.dashes.com/anil/xmlindex.php">something like this</a>. <a href="http://q.queso.com/index.php?archives/001000.php">Jason Levine has more links</a> to those involved. I spoke with one of the people who implemented it, and she claims it wasn't a protest as such, more of an inside joke. Point taken: the entire point of an aggregator (and syndication in general) is to make everyone's words look the same. Counterpoint: the default in most weblog systems is to only publish excerpts in RSS feeds; nobody's forcing you to publish full posts. This would probably be a good place to insert a Zen quote about attachment, but my mind is too fuzzy to find it.</p>
|
||||
|
||||
<p><cite>Timothy Appnel</cite>: <a href="http://www.mplode.com/tima/archives/000107.html">More FFKAR, RDF, and FOAF</a>. FFKAR is <q>the format formerly known as RSS</q>. <a href="http://www.intertwingly.net/blog/840.html">Sam has already implemented it</a>.</p>
|
||||
|
||||
<p><cite>Nicholas Avenell</cite>: <a href="http://www.aquarionics.com/nodes/view.php?name=esf">ESF</a>. <q>Are you also fed up with the continuing war between RSS 0.9* and 1.0 and 2.0 and whatever else they invent today? Me too. So today I invented the Epistula Syndication Format. ESF. It isn't XML. It isn't RDF. It's just data.</q> <a href="http://www.intertwingly.net/blog/">Sam</a> would love it, then. But <a href="http://www.movabletype.org/docs/mtmanual_tags.html#date tag formats">Movable Type doesn't support outputting dates in Unix timestamp format</a>, which could be an impediment to mainstream acceptance.</p>
|
||||
|
||||
<p><cite>Shelley Powers</cite>: <a href="http://weblog.burningbird.net/archives/000544.php">Consumer Rights and RSS</a>. <q>I'm not buying into RSS 0.9x. I'm not buying into RSS 2.0. I'm not buying into RSS 1.0. I changed my RSS 0.91 and RSS 1.0 templates to read the following:</q></p>
|
||||
|
||||
<blockquote>
|
||||
<p><strong>RSS not supported here</strong></p>
|
||||
<p>This weblog does not support RSS 0.9x, RSS 2.0, or RSS 1.0. If you wish to view entries, may I suggest that you visit the weblog, and save your fast skimming for the New York Times and Wall Street Journal.</p>
|
||||
</blockquote>
|
||||
|
||||
<p>I'm sure this is some sort of DMCA violation or something, but here goes:</p>
|
||||
|
||||
<blockquote>
|
||||
<p><code>import urllib, re; print "<rss><channel>\n <title>Burningbird</title>\n <link>http://weblog.burningbird.net/</link>\n <language>en-us</language>\n </channel>\n" + "\n".join(["<item><title>%s</title><link>%s</link></item>" % t for t in re.compile(r'dc:title="(.*?)"\s*dc:identifier="(.*?)"', re.DOTALL).findall(urllib.urlopen('http://weblog.burningbird.net/').read())]) + "</rss>"</code></p>
|
||||
</blockquote>
|
||||
|
||||
<p></p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-25T00:38:31-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Stark raving sane</title>
|
||||
<link>http://diveintomark.org/archives/2002/09/24.html#stark_raving_sane</link>
|
||||
<description>Sam Ruby is stark raving mad.</description>
|
||||
<guid isPermaLink="false">1839@http://diveintomark.org/</guid>
|
||||
<content:encoded><![CDATA[<p><cite>Sam Ruby</cite>: <a href="http://www.intertwingly.net/blog/844.html">Stark raving mad</a>.</p>
|
||||
|
||||
<blockquote>
|
||||
<p>This post was entered in Radio, extracted using a batch file via some UserTalk, parsed using Perl, cleaned up by tidy and a C program of my own design, transferred to intertwingly using scp, and then ssh triggers unpacking on the destination site, where a shell script takes over: invokes indexing using Jakarta's Lucene, and then a python script pings weblogs.com and blo.gs.</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Tom Stoppard (<cite>Rosencrantz and Guildenstern are Dead</cite>):</p>
|
||||
|
||||
<blockquote>
|
||||
<p>Guildenstern: <q>A man talking sense to himself is no madder than a man talking nonsense not to himself.</q><br />
|
||||
Rosencrantz: <q>Or just as mad.</q><br />
|
||||
Guildenstern: <q>Or just as mad.</q><br />
|
||||
Rosencrantz: <q>And he does both.</q><br />
|
||||
Guildenstern: <q>So there you are.</q><br />
|
||||
Rosencrantz: <q>Stark raving sane.</q></p>
|
||||
</blockquote>
|
||||
|
||||
<p></p>]]></content:encoded>
|
||||
<dc:subject></dc:subject>
|
||||
<dc:date>2002-09-24T22:05:32-05:00</dc:date>
|
||||
</item>
|
||||
|
||||
|
||||
</channel>
|
||||
</rss>
|
66
sample/rss/rssTwoExample.xml
Normal file
66
sample/rss/rssTwoExample.xml
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- RSS generated by Radio UserLand v8.0.5 on Tue, 17 Sep 2002 20:40:06 GMT -->
|
||||
<rss version="2.0" xmlns="http://backend.userland.com/rss2" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">
|
||||
<channel>
|
||||
<title>Scripting News</title>
|
||||
<link>http://www.scripting.com/</link>
|
||||
<description>A weblog about scripting and stuff like that.</description>
|
||||
<language>en-us</language>
|
||||
<blogChannel:blogRoll>http://radio.weblogs.com/0001015/userland/scriptingNewsLeftLinks.opml</blogChannel:blogRoll>
|
||||
<blogChannel:mySubscriptions>http://radio.weblogs.com/0001015/gems/mySubscriptions.opml</blogChannel:mySubscriptions>
|
||||
<blogChannel:blink>http://inessential.com/</blogChannel:blink>
|
||||
<copyright>Copyright 1997-2002 Dave Winer</copyright>
|
||||
<lastBuildDate>Tue, 17 Sep 2002 20:40:06 GMT</lastBuildDate>
|
||||
<docs>http://backend.userland.com/rss</docs>
|
||||
<generator>Radio UserLand v8.0.5</generator>
|
||||
<category domain="Syndic8">1765</category>
|
||||
<managingEditor>dave@userland.com</managingEditor>
|
||||
<webMaster>dave@userland.com</webMaster>
|
||||
<ttl>60</ttl>
|
||||
<item>
|
||||
<description><a href="http://frontier.userland.com/stories/storyReader$10657">JRobb</a>: "I am proud to announce the launch of Frontier 9."</description>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:11:01:55AM</guid>
|
||||
<pubDate>Tue, 17 Sep 2002 11:01:55 GMT</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<description><a href="http://jrobb.userland.com/stories/2002/09/17/rogueEmail.html">How to</a> ruin your life in one email.</description>
|
||||
<pubDate>Tue, 17 Sep 2002 17:41:35 GMT</pubDate>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:10:41:35AM</guid>
|
||||
</item>
|
||||
<item>
|
||||
<description><a href="http://blogs.salon.com/0001236/2002/09/17.html#a805">Michel Vuijlsteke</a>: "And the hits started rolling in."</description>
|
||||
<pubDate>Tue, 17 Sep 2002 17:04:52 GMT</pubDate>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:10:04:52AM</guid>
|
||||
</item>
|
||||
<item>
|
||||
<description><a href="http://inessential.com/2002/09/16.php">Brent Simmons</a>: "For RSS adoption to continue, stability is important. Developers should not spend their time scrambling to support new specs: they should spend their time building better apps." <i>Exactly. </i></description>
|
||||
<pubDate>Tue, 17 Sep 2002 11:55:37 GMT</pubDate>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:4:55:37AM</guid>
|
||||
</item>
|
||||
<item>
|
||||
<description><a href="http://bitworking.org/Sep2002.html#X631678518613884736">Aggie</a> is the first aggregator to support <a href="http://backend.userland.com/rss">RSS 2.0</a>.</description>
|
||||
<pubDate>Tue, 17 Sep 2002 14:01:03 GMT</pubDate>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:7:01:03AM</guid>
|
||||
</item>
|
||||
<item>
|
||||
<description><a href="http://radio.weblogs.com/0100875/outlines/rcsAggregatorCache/">Mikel Maron</a>: "With this tool, the Radio Community Server can act as a RSS Cache for Radio Userland Aggregators."</description>
|
||||
<pubDate>Tue, 17 Sep 2002 15:12:50 GMT</pubDate>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:8:12:50AM</guid>
|
||||
</item>
|
||||
<item>
|
||||
<description>With almost 2.5 million page reads in the last year, Scripting News would not qualify for the small-flow categories in the <a href="http://www.onlinejournalismawards.org/pr-2002finalists3.html">Online Journalism Awards</a>. Their cutoff is 200,000 visits per month. We did more than that.</description>
|
||||
<pubDate>Tue, 17 Sep 2002 16:50:19 GMT</pubDate>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:9:50:19AM</guid>
|
||||
</item>
|
||||
<item>
|
||||
<description><a href="http://radio.weblogs.com/0001227/2002/09/17.html">Sean Gallagher</a>: "Detroit is a city that looks like you might expect a city to look after a neutron bomb went off in it; most of the buildings are still standing, but the people are gone."</description>
|
||||
<pubDate>Tue, 17 Sep 2002 14:09:14 GMT</pubDate>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:7:09:14AM</guid>
|
||||
</item>
|
||||
<item>
|
||||
<description>The NY Times <a href="http://www.nytimes.com/2002/09/17/technology/17AOL.html?ex=1032840000&en=9bebebadbb60c3a2&ei=5007&partner=USERLAND">reports</a> that there's a move to push Steve Case out as chairman of AOL-Time-Warner; and that Charles Simonyi, an early Microsoft employee, <a href="http://www.nytimes.com/2002/09/17/technology/17SOFT.html?ex=1032840000&en=32d4d1af8909b6e6&ei=5007&partner=USERLAND">has left to start</a> a new software company.</description>
|
||||
<pubDate>Tue, 17 Sep 2002 10:14:55 GMT</pubDate>
|
||||
<guid>http://scriptingnews.userland.com/backissues/2002/09/17#When:10:14:55AM</guid>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
84
sample/rss/rss_recent.rb
Normal file
84
sample/rss/rss_recent.rb
Normal file
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require "nkf"
|
||||
class String
|
||||
# From tdiary.rb
|
||||
def shorten( len = 120 )
|
||||
lines = NKF::nkf( "-e -m0 -f#{len}", self.gsub( /\n/, ' ' ) ).split( /\n/ )
|
||||
lines[0].concat( '...' ) if lines[0] and lines[1]
|
||||
lines[0]
|
||||
end
|
||||
end
|
||||
|
||||
require "rss/parser"
|
||||
require "rss/1.0"
|
||||
require "rss/2.0"
|
||||
require "rss/syndication"
|
||||
require "rss/dublincore"
|
||||
|
||||
items = []
|
||||
verbose = false
|
||||
|
||||
def error(exception)
|
||||
mark = "=" * 20
|
||||
mark = "#{mark} error #{mark}"
|
||||
puts mark
|
||||
puts exception.class
|
||||
puts exception.message
|
||||
puts exception.backtrace
|
||||
puts mark
|
||||
end
|
||||
before_time = Time.now
|
||||
ARGV.each do |fname|
|
||||
if fname == '-v'
|
||||
verbose = true
|
||||
next
|
||||
end
|
||||
rss = nil
|
||||
f = File.new(fname).read
|
||||
begin
|
||||
## do validate parse
|
||||
rss = RSS::Parser.parse(f)
|
||||
rescue RSS::InvalidRSSError
|
||||
error($!) if verbose
|
||||
## do non validate parse for invalid RSS 1.0
|
||||
begin
|
||||
rss = RSS::Parser.parse(f, false)
|
||||
rescue RSS::Error
|
||||
## invalid RSS.
|
||||
error($!) if verbose
|
||||
end
|
||||
rescue RSS::Error
|
||||
error($!) if verbose
|
||||
end
|
||||
if rss.nil?
|
||||
puts "#{fname} does not include RSS 1.0 or 0.9x/2.0"
|
||||
else
|
||||
begin
|
||||
rss.output_encoding = "euc-jp"
|
||||
rescue RSS::UnknownConversionMethodError
|
||||
error($!) if verbose
|
||||
end
|
||||
rss.items.each do |item|
|
||||
if item.respond_to?(:pubDate) and item.pubDate
|
||||
class << item
|
||||
alias_method(:dc_date, :pubDate)
|
||||
end
|
||||
end
|
||||
if item.respond_to?(:dc_date) and item.dc_date
|
||||
items << [rss.channel, item]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
processing_time = Time.now - before_time
|
||||
|
||||
items.sort do |x, y|
|
||||
y[1].dc_date <=> x[1].dc_date
|
||||
end[0..20].each do |channel, item|
|
||||
puts "#{item.dc_date.localtime.iso8601} : " <<
|
||||
"#{channel.title} : #{item.title}"
|
||||
puts " description : #{item.description.shorten(50)}" if item.description
|
||||
end
|
||||
|
||||
puts "Processing Time : #{processing_time}s"
|
50
sample/rss/sampleRss.xml
Normal file
50
sample/rss/sampleRss.xml
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<rss version="0.91">
|
||||
<channel>
|
||||
<title>WriteTheWeb</title>
|
||||
<link>http://writetheweb.com</link>
|
||||
<description>News for web users that write back</description>
|
||||
<language>en-us</language>
|
||||
<copyright>Copyright 2000, WriteTheWeb team.</copyright>
|
||||
<managingEditor>editor@writetheweb.com</managingEditor>
|
||||
<webMaster>webmaster@writetheweb.com</webMaster>
|
||||
<image>
|
||||
<title>WriteTheWeb</title>
|
||||
<url>http://writetheweb.com/images/mynetscape88.gif</url>
|
||||
<link>http://writetheweb.com</link>
|
||||
<width>88</width>
|
||||
<height>31</height>
|
||||
<description>News for web users that write back</description>
|
||||
</image>
|
||||
<item>
|
||||
<title>Giving the world a pluggable Gnutella</title>
|
||||
<link>http://writetheweb.com/read.php?item=24</link>
|
||||
<description>WorldOS is a framework on which to build programs that work like Freenet or Gnutella -allowing distributed applications using peer-to-peer routing.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Syndication discussions hot up</title>
|
||||
<link>http://writetheweb.com/read.php?item=23</link>
|
||||
<description>After a period of dormancy, the Syndication mailing list has become active again, with contributions from leaders in traditional media and Web syndication.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Personal web server integrates file sharing and messaging</title>
|
||||
<link>http://writetheweb.com/read.php?item=22</link>
|
||||
<description>The Magi Project is an innovative project to create a combined personal web server and messaging system that enables the sharing and synchronization of information across desktop, laptop and palmtop devices.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Syndication and Metadata</title>
|
||||
<link>http://writetheweb.com/read.php?item=21</link>
|
||||
<description>RSS is probably the best known metadata format around. RDF is probably one of the least understood. In this essay, published on my O'Reilly Network weblog, I argue that the next generation of RSS should be based on RDF.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>UK bloggers get organised</title>
|
||||
<link>http://writetheweb.com/read.php?item=20</link>
|
||||
<description>Looks like the weblogs scene is gathering pace beyond the shores of the US. There's now a UK-specific page on weblogs.com, and a mailing list at egroups.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Yournamehere.com more important than anything</title>
|
||||
<link>http://writetheweb.com/read.php?item=19</link>
|
||||
<description>Whatever you're publishing on the web, your site name is the most valuable asset you have, according to Carl Steadman.</description>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
176
sample/rss/slashdot.rdf
Normal file
176
sample/rss/slashdot.rdf
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:slash="http://slashcode.com/rss/1.0/modules/Slash/"
|
||||
xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
|
||||
xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
|
||||
>
|
||||
|
||||
<channel rdf:about="http://slashdot.jp/">
|
||||
<title>スラッシュドット ジャパン</title>
|
||||
<link>http://slashdot.jp/</link>
|
||||
<description>アレゲなニュースと雑談サイト</description>
|
||||
<dc:language>ja-jp</dc:language>
|
||||
<dc:rights>Copyright(c) 2001, Slashdot Japan</dc:rights>
|
||||
<dc:date>2003-03-02T10:13:10+00:00</dc:date>
|
||||
<dc:publisher>Slashdot Japan</dc:publisher>
|
||||
<dc:creator>slashmaster@slashdot.jp</dc:creator>
|
||||
<dc:subject>Technology</dc:subject>
|
||||
<syn:updatePeriod>hourly</syn:updatePeriod>
|
||||
<syn:updateFrequency>1</syn:updateFrequency>
|
||||
<syn:updateBase>1970-01-01T00:00+00:00</syn:updateBase>
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/02/0924255&topic=1" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/02/0845229&topic=62" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/02/0428233&topic=89" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/01/1345238&topic=1" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/01/1141203&topic=42" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/01/1132259&topic=31" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/01/1045237&topic=31" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/01/1045214&topic=68" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/01/097247&topic=72" />
|
||||
<rdf:li resource="http://slashdot.jp/article.pl?sid=03/03/01/0752218&topic=16" />
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
<image rdf:resource="http://slashdot.jp/images/topics/topicslashdot.gif" />
|
||||
<textinput rdf:resource="http://slashdot.jp/search.pl" />
|
||||
</channel>
|
||||
|
||||
<image rdf:about="http://slashdot.jp/images/topics/topicslashdot.gif">
|
||||
<title>スラッシュドット ジャパン</title>
|
||||
<url>http://slashdot.jp/images/topics/topicslashdot.gif</url>
|
||||
<link>http://slashdot.jp/</link>
|
||||
</image>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/02/0924255&topic=1">
|
||||
<title>PS2制御のドライビング・シミュレータ</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/02/0924255&topic=1</link>
|
||||
<dc:creator>yourCat</dc:creator>
|
||||
<dc:subject>news</dc:subject>
|
||||
<dc:date>2003-03-02T09:18:36+00:00</dc:date>
|
||||
<slash:department>安全運転のためなのを忘れそう</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>5</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/02/0845229&topic=62">
|
||||
<title>脳は音の速さを知っている</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/02/0845229&topic=62</link>
|
||||
<dc:creator>yourCat</dc:creator>
|
||||
<dc:subject>science</dc:subject>
|
||||
<dc:date>2003-03-02T08:40:53+00:00</dc:date>
|
||||
<slash:department>40mというのが面白い</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>17</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/02/0428233&topic=89">
|
||||
<title>外来語言い換え、第2回語案の提案を募集中</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/02/0428233&topic=89</link>
|
||||
<dc:creator>GetSet</dc:creator>
|
||||
<dc:subject>japan</dc:subject>
|
||||
<dc:date>2003-03-02T04:26:27+00:00</dc:date>
|
||||
<slash:department>言い換えない方が判り易いことも</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>85</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/01/1345238&topic=1">
|
||||
<title>バイク用ETCが実用化へ</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/01/1345238&topic=1</link>
|
||||
<dc:creator>GetSet</dc:creator>
|
||||
<dc:subject>news</dc:subject>
|
||||
<dc:date>2003-03-01T13:41:52+00:00</dc:date>
|
||||
<slash:department>グローブ外すのに慌てなくていいのね</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>122</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/01/1141203&topic=42">
|
||||
<title>「ジョーバ」でGo!</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/01/1141203&topic=42</link>
|
||||
<dc:creator>GetSet</dc:creator>
|
||||
<dc:subject>humor</dc:subject>
|
||||
<dc:date>2003-03-01T11:39:37+00:00</dc:date>
|
||||
<slash:department>私の愛馬は凶暴です</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>28</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/01/1132259&topic=31">
|
||||
<title>ラグナロクオンラインで大規模な冤罪・追放騒動</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/01/1132259&topic=31</link>
|
||||
<dc:creator>GetSet</dc:creator>
|
||||
<dc:subject>games</dc:subject>
|
||||
<dc:date>2003-03-01T11:23:59+00:00</dc:date>
|
||||
<slash:department>正直なユーザが一番の被害者かも</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>70</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/01/1045237&topic=31">
|
||||
<title>グリッドを使った100万人用のゲームサーバ</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/01/1045237&topic=31</link>
|
||||
<dc:creator>Oliver</dc:creator>
|
||||
<dc:subject>games</dc:subject>
|
||||
<dc:date>2003-03-01T10:45:03+00:00</dc:date>
|
||||
<slash:department>PS3先取り</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>24</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/01/1045214&topic=68">
|
||||
<title>Sun、UltraSPARCのスループットを3年後には30倍に</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/01/1045214&topic=68</link>
|
||||
<dc:creator>Oliver</dc:creator>
|
||||
<dc:subject>sun</dc:subject>
|
||||
<dc:date>2003-03-01T10:44:31+00:00</dc:date>
|
||||
<slash:department>バスというボトルネック</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>21</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/01/097247&topic=72">
|
||||
<title>ハイテク監視システムやぶられ、127億円の宝石が盗難</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/01/097247&topic=72</link>
|
||||
<dc:creator>Oliver</dc:creator>
|
||||
<dc:subject>money</dc:subject>
|
||||
<dc:date>2003-03-01T09:05:46+00:00</dc:date>
|
||||
<slash:department>史上最強のクラッキング?</slash:department>
|
||||
<slash:section>security</slash:section>
|
||||
<slash:comments>29</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<item rdf:about="http://slashdot.jp/article.pl?sid=03/03/01/0752218&topic=16">
|
||||
<title>国内の航空管制が一時全停止</title>
|
||||
<link>http://slashdot.jp/article.pl?sid=03/03/01/0752218&topic=16</link>
|
||||
<dc:creator>Oliver</dc:creator>
|
||||
<dc:subject>bug</dc:subject>
|
||||
<dc:date>2003-03-01T07:51:30+00:00</dc:date>
|
||||
<slash:department>3台で多数決を</slash:department>
|
||||
<slash:section>articles</slash:section>
|
||||
<slash:comments>126</slash:comments>
|
||||
<slash:hitparade></slash:hitparade>
|
||||
</item>
|
||||
|
||||
<textinput rdf:about="http://slashdot.jp/search.pl">
|
||||
<title>Search スラッシュドット ジャパン</title>
|
||||
<description>Search スラッシュドット ジャパン stories</description>
|
||||
<name>query</name>
|
||||
<link>http://slashdot.jp/search.pl</link>
|
||||
</textinput>
|
||||
|
||||
</rdf:RDF>
|
76
sample/rss/slashdotorg.rdf
Normal file
76
sample/rss/slashdotorg.rdf
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://my.netscape.com/rdf/simple/0.9/">
|
||||
|
||||
<channel>
|
||||
<title>Slashdot</title>
|
||||
<link>http://slashdot.org/</link>
|
||||
<description>News for nerds, stuff that matters</description>
|
||||
</channel>
|
||||
|
||||
<image>
|
||||
<title>Slashdot</title>
|
||||
<url>http://images.slashdot.org/topics/topicslashdot.gif</url>
|
||||
<link>http://slashdot.org/</link>
|
||||
</image>
|
||||
|
||||
<item>
|
||||
<title>McDonalds to go Wireless?</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/11/135255</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Feds Move to Secure Net</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/11/0246210</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Linus Comments on SCO v IBM</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/11/0137251</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>New Windows Worm Inching Around Internet</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/11/0058219</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Tcl Core Team Interview</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/10/229219</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>MA Dept. of Revenue consider Linux</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/10/2156202</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Perl 6: Apocalypse 6 Released</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/10/2134229</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>SuSE may drop out of UnitedLinux</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/10/212241</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>New Legit Napster Service Coming</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/10/1931252</link>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Swapping Clock Cycles for Free Music?</title>
|
||||
<link>http://slashdot.org/article.pl?sid=03/03/10/1845230</link>
|
||||
</item>
|
||||
|
||||
<textinput>
|
||||
<title>Search Slashdot</title>
|
||||
<description>Search Slashdot stories</description>
|
||||
<name>query</name>
|
||||
<link>http://slashdot.org/search.pl</link>
|
||||
</textinput>
|
||||
|
||||
</rdf:RDF>
|
118
sample/rss/tdiary_plugin/rss-recent.rb
Normal file
118
sample/rss/tdiary_plugin/rss-recent.rb
Normal file
|
@ -0,0 +1,118 @@
|
|||
# rss-recent.rb: RSS recent plugin
|
||||
#
|
||||
# rss_recnet: show recnet list from RSS
|
||||
# parameters (default):
|
||||
# url: URL of RSS
|
||||
# max: max of list itmes(5)
|
||||
# cache_time: cache time(second) of RSS(60*60)
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2003 Kouhei Sutou <kou@cozmixng.org>
|
||||
# Distributed under the GPL
|
||||
#
|
||||
|
||||
require "rss/rss"
|
||||
|
||||
RSS_RECENT_FIELD_SEPARATOR = "\0"
|
||||
RSS_RECENT_VERSION = "0.0.2"
|
||||
RSS_RECENT_CONTENT_TYPE = {
|
||||
"User-Agent" => "tDiary RSS recent plugin version #{RSS_RECENT_VERSION}. " <<
|
||||
"Using RSS parser version is #{::RSS::VERSION}."
|
||||
}
|
||||
|
||||
|
||||
def rss_recent(url, max=5, cache_time=3600)
|
||||
cache_file = "#{@cache_path}/rss-recent.#{CGI.escape(url)}"
|
||||
|
||||
rss_recent_cache_rss(url, cache_file, cache_time.to_i)
|
||||
|
||||
return '' unless test(?r, cache_file)
|
||||
|
||||
rv = "<ul>\n"
|
||||
File.open(cache_file) do |f|
|
||||
max.to_i.times do
|
||||
title = f.gets(RSS_RECENT_FIELD_SEPARATOR)
|
||||
break if title.nil?
|
||||
rv << '<li>'
|
||||
link = f.gets(RSS_RECENT_FIELD_SEPARATOR)
|
||||
unless link.nil?
|
||||
rv << %Q!<a href="#{CGI.escapeHTML(link.chomp(RSS_RECENT_FIELD_SEPARATOR))}">!
|
||||
end
|
||||
rv << CGI::escapeHTML(title.chomp(RSS_RECENT_FIELD_SEPARATOR))
|
||||
rv << '</a>' unless link.nil?
|
||||
rv << "</li>\n"
|
||||
end
|
||||
end
|
||||
rv << "</ul>\n"
|
||||
|
||||
rv
|
||||
end
|
||||
|
||||
class InvalidResourceError < StandardError; end
|
||||
|
||||
def rss_recent_cache_rss(url, cache_file, cache_time)
|
||||
|
||||
begin
|
||||
raise if Time.now > File.mtime(cache_file) + cache_time
|
||||
rescue
|
||||
require 'net/http'
|
||||
require 'uri/generic'
|
||||
require 'rss/parser'
|
||||
require 'rss/1.0'
|
||||
require 'rss/2.0'
|
||||
|
||||
begin
|
||||
ur = URI.parse(url)
|
||||
|
||||
raise URI::InvalidURIError if ur.scheme != "http"
|
||||
|
||||
rss_source = rss_recent_fetch_rss(ur)
|
||||
|
||||
# parse RSS
|
||||
rss = ::RSS::Parser.parse(rss_source, false)
|
||||
raise ::RSS::Error if rss.nil?
|
||||
|
||||
# pre processing
|
||||
begin
|
||||
rss.output_encoding = charset
|
||||
rescue ::RSS::UnknownConversionMethodError
|
||||
end
|
||||
|
||||
tlary = rss.items.collect{|item| [item.title, item.link]}
|
||||
rss_recent_write_to_cache(cache_file, tlary)
|
||||
|
||||
rescue URI::InvalidURIError
|
||||
rss_recent_write_to_cache(cache_file, [['Invalid URI', url]])
|
||||
rescue InvalidResourceError, ::RSS::Error
|
||||
rss_recent_write_to_cache(cache_file, [['Invalid Resource', url]])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def rss_recent_fetch_rss(uri)
|
||||
rss = ''
|
||||
begin
|
||||
Net::HTTP.start(uri.host, uri.port || 80) do |http|
|
||||
path = uri.path
|
||||
path << "?#{uri.query}" if uri.query
|
||||
req = http.request_get(path)
|
||||
raise InvalidResourceError unless req.code == "200"
|
||||
rss << req.body
|
||||
end
|
||||
rescue TimeoutError, SocketError
|
||||
raise InvalidResourceError
|
||||
end
|
||||
rss
|
||||
end
|
||||
|
||||
def rss_recent_write_to_cache(cache_file, array_of_titles_and_links)
|
||||
File.open(cache_file, 'w') do |f|
|
||||
f.flock(File::LOCK_EX)
|
||||
array_of_titles_and_links.each do |title, link|
|
||||
f << "#{title}#{RSS_RECENT_FIELD_SEPARATOR}"
|
||||
f << "#{link}#{RSS_RECENT_FIELD_SEPARATOR}"
|
||||
end
|
||||
f.flock(File::LOCK_UN)
|
||||
end
|
||||
end
|
63
sample/rss/w3c.rdf
Normal file
63
sample/rss/w3c.rdf
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml-stylesheet href="http://www.w3.org/2000/08/w3c-synd/style.css" type="text/css"?>
|
||||
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:hr="http://www.w3.org/2000/08/w3c-synd/#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/">
|
||||
<channel rdf:about="http://www.w3.org/2000/08/w3c-synd/home.rss">
|
||||
<title>World Wide Web Consortium</title>
|
||||
<description>Leading the Web to its Full Potential...</description>
|
||||
<link>http://www.w3.org/</link>
|
||||
<dc:date>2003-03-11T00:11:20Z</dc:date>
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<rdf:li rdf:resource="http://www.w3.org/News/2003#item50"/>
|
||||
<rdf:li rdf:resource="http://www.w3.org/News/2003#item53"/>
|
||||
<rdf:li rdf:resource="http://www.w3.org/News/2003#item52"/>
|
||||
<rdf:li rdf:resource="http://www.w3.org/News/2003#item51"/>
|
||||
<rdf:li rdf:resource="http://www.w3.org/News/2003#item49"/>
|
||||
<rdf:li rdf:resource="http://www.w3.org/News/2003#item45"/>
|
||||
<rdf:li rdf:resource="http://www.w3.org/News/2003#item46"/>
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
</channel>
|
||||
<item rdf:about="http://www.w3.org/News/2003#item50">
|
||||
<title>W3C Hosts Technical Plenary and All-Group Meeting</title>
|
||||
<description>3 March 2003: W3C holds its third annual Technical Plenary and All Working Group Meeting from 3-7 March in Cambridge, MA, USA. 30 W3C Working Groups and Interest Groups hold face-to-face meetings. Mid-week, many of the more than 400 participants attend the all day public plenary, by far the largest group in the event's history. If your organization would like to join W3C, please refer to the Membership page. (News archive)</description>
|
||||
<link>http://www.w3.org/News/2003#item50</link>
|
||||
<dc:date>2003-03-03</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.w3.org/News/2003#item53">
|
||||
<title>China International Forum on WWW's Development Announced</title>
|
||||
<description>10 March 2003: The China International Forum on WWW's Development 2003 will be held in Beijing, China on 16-17 April. W3C Team members Judy Brewer, Martin Dürst, Ivan Herman, Philipp Hoschka and Matt May present keynotes and tutorials. Attendees will participate in panels on accessibility, SVG, mobile Web, the Semantic Web, VoiceXML and internationalization. Registration is open. The event is co-organized by the China Computer Federation and the W3C Office in Hong Kong. (News archive)</description>
|
||||
<link>http://www.w3.org/News/2003#item53</link>
|
||||
<dc:date>2003-03-10</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.w3.org/News/2003#item52">
|
||||
<title>Call for Participation: W3C Teleconference on Collaboration</title>
|
||||
<description>4 March 2003: W3C is pleased to announce the first in a series of teleconferences on Web accessibility research. Researchers and practitioners in document collaboration, human-computer interaction, assistive technologies, disability studies, Web accessibility, and related fields are invited. The event is sponsored by the Web Accessibility Initiative's Research and Development Interest Group. The first telecon is tentatively 14 April. Position papers are due 21 March. Please refer to the call for papers. (News archive)</description>
|
||||
<link>http://www.w3.org/News/2003#item52</link>
|
||||
<dc:date>2003-03-04</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.w3.org/News/2003#item51">
|
||||
<title>Web Services Description Language (WSDL) 1.2 Working Draft Published</title>
|
||||
<description>3 March 2003: The Web Services Description Working Group has released an updated Working Draft of the Web Services Description Language (WSDL) Version 1.2. WSDL is a model and an XML format for describing Web services that allows separation of abstract functionality from concrete details. Read about Web Services. (News archive)</description>
|
||||
<link>http://www.w3.org/News/2003#item51</link>
|
||||
<dc:date>2003-03-03</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.w3.org/News/2003#item49">
|
||||
<title>W3C Team Talks in March</title>
|
||||
<description>1 March 2003: Browse upcoming W3C appearances and events. (News archive)</description>
|
||||
<link>http://www.w3.org/News/2003#item49</link>
|
||||
<dc:date>2003-03-01</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.w3.org/News/2003#item45">
|
||||
<title>W3C Co-Sponsors 23rd Internationalization & Unicode Conference</title>
|
||||
<description>26 February 2003: Registration is open for the 23rd Internationalization & Unicode Conference to be held 24-26 March in Prague, Czech Republic, near most major cities in Europe. Come and meet W3C Team members Martin Dürst, Richard Ishida, and Chris Lilley who are presenting. The event is the premier technical conference worldwide for software and Web internationalization. Read about Unicode and the W3C Internationalization Activity. (News archive)</description>
|
||||
<link>http://www.w3.org/News/2003#item45</link>
|
||||
<dc:date>2003-02-26</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.w3.org/News/2003#item46">
|
||||
<title>CSS3 Text Last Call Working Draft Published</title>
|
||||
<description>26 February 2003: The CSS Working Group has released a second Last Call Working Draft of the CSS3 module: Text incorporating all comments from the first Last Call. The group welcomes feedback through 5 March. The document is a set of text formatting properties. Many address international contexts, particularly East Asian and bidirectional text. Visit the CSS home page. (News archive)</description>
|
||||
<link>http://www.w3.org/News/2003#item46</link>
|
||||
<dc:date>2003-02-26</dc:date>
|
||||
</item>
|
||||
</rdf:RDF>
|
88
sample/rss/wiliki.rss
Normal file
88
sample/rss/wiliki.rss
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="euc-jp" ?>
|
||||
<rdf:RDF
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
>
|
||||
<channel rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi"><title>WiLiKi</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi</link>
|
||||
<description>WiLiKi, a Wiki engine written in Scheme</description>
|
||||
<items><rdf:Seq><rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?todo&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aWindows%2fVC%2b%2b&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aBugs&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?%b5%ba&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aCygwin&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aSpamFilter&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?skimu&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%3aRSSMix&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?SHIMADA&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%a5%bd%a1%bc%a5%b9%b2%f2%c6%c9&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?MakotoS&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%3aWishList&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aPackages&l=jp" />
|
||||
<rdf:li rdf:resource="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aMacOSX&l=jp" />
|
||||
</rdf:Seq></items>
|
||||
|
||||
</channel>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?todo&l=jp"><title>todo</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?todo&l=jp</link>
|
||||
<dc:date>2003-03-15T11:47:00+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aWindows%2fVC%2b%2b&l=jp"><title>Gauche:Windows/VC++</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aWindows%2fVC%2b%2b&l=jp</link>
|
||||
<dc:date>2003-03-15T04:41:42+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aBugs&l=jp"><title>Gauche:Bugs</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aBugs&l=jp</link>
|
||||
<dc:date>2003-03-15T01:59:57+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?%b5%ba&l=jp"><title>µº</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?%b5%ba&l=jp</link>
|
||||
<dc:date>2003-03-14T17:47:24+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aCygwin&l=jp"><title>Gauche:Cygwin</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aCygwin&l=jp</link>
|
||||
<dc:date>2003-03-13T15:34:27+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aSpamFilter&l=jp"><title>Gauche:SpamFilter</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aSpamFilter&l=jp</link>
|
||||
<dc:date>2003-03-13T11:46:12+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?skimu&l=jp"><title>skimu</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?skimu&l=jp</link>
|
||||
<dc:date>2003-03-13T04:46:56+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%3aRSSMix&l=jp"><title>WiLiKi:RSSMix</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%3aRSSMix&l=jp</link>
|
||||
<dc:date>2003-03-13T04:27:01+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi&l=jp"><title>WiLiKi</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi&l=jp</link>
|
||||
<dc:date>2003-03-13T01:01:11+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?SHIMADA&l=jp"><title>SHIMADA</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?SHIMADA&l=jp</link>
|
||||
<dc:date>2003-03-11T05:19:03+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%a5%bd%a1%bc%a5%b9%b2%f2%c6%c9&l=jp"><title>WiLiKi¥½¡¼¥¹²òÆÉ</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%a5%bd%a1%bc%a5%b9%b2%f2%c6%c9&l=jp</link>
|
||||
<dc:date>2003-03-10T08:46:29+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?MakotoS&l=jp"><title>MakotoS</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?MakotoS&l=jp</link>
|
||||
<dc:date>2003-03-10T08:00:47+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%3aWishList&l=jp"><title>WiLiKi:WishList</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?WiLiKi%3aWishList&l=jp</link>
|
||||
<dc:date>2003-03-10T07:56:40+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aPackages&l=jp"><title>Gauche:Packages</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aPackages&l=jp</link>
|
||||
<dc:date>2003-03-09T10:40:43+00:00</dc:date>
|
||||
</item>
|
||||
<item rdf:about="http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aMacOSX&l=jp"><title>Gauche:MacOSX</title>
|
||||
<link>http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3aMacOSX&l=jp</link>
|
||||
<dc:date>2003-03-09T08:05:22+00:00</dc:date>
|
||||
</item>
|
||||
</rdf:RDF>
|
100
test/rss/common.rb
Normal file
100
test/rss/common.rb
Normal file
|
@ -0,0 +1,100 @@
|
|||
require 'test/my-assertions'
|
||||
|
||||
module TestRSSMixin
|
||||
|
||||
include RSS
|
||||
|
||||
XMLDECL_VERSION = "1.0"
|
||||
XMLDECL_ENCODING = "UTF-8"
|
||||
XMLDECL_STANDALONE = "no"
|
||||
|
||||
RDF_ABOUT = "http://www.xml.com/xml/news.rss"
|
||||
RDF_RESOURCE = "http://xml.com/universal/images/xml_tiny.gif"
|
||||
TITLE_VALUE = "XML.com"
|
||||
LINK_VALUE = "http://xml.com/pub"
|
||||
URL_VALUE = "http://xml.com/universal/images/xml_tiny.gif"
|
||||
NAME_VALUE = "hogehoge"
|
||||
DESCRIPTION_VALUE = "
|
||||
XML.com features a rich mix of information and services
|
||||
for the XML community.
|
||||
"
|
||||
RESOURCES = [
|
||||
"http://xml.com/pub/2000/08/09/xslt/xslt.html",
|
||||
"http://xml.com/pub/2000/08/09/rdfdb/index.html",
|
||||
]
|
||||
|
||||
private
|
||||
def make_xmldecl(v=XMLDECL_VERSION, e=XMLDECL_ENCODING, s=XMLDECL_STANDALONE)
|
||||
rv = "<?xml version='#{v}'"
|
||||
rv << " encoding='#{e}'" if e
|
||||
rv << " standalone='#{s}'" if s
|
||||
rv << "?>"
|
||||
rv
|
||||
end
|
||||
|
||||
def make_RDF(content=nil, xmlns=[])
|
||||
<<-EORSS
|
||||
#{make_xmldecl}
|
||||
<rdf:RDF xmlns="#{URI}" xmlns:rdf="#{RDF::URI}"
|
||||
#{xmlns.collect {|pre, uri| "xmlns:#{pre}='#{uri}'"}.join(' ')}>
|
||||
#{block_given? ? yield : content}
|
||||
</rdf:RDF>
|
||||
EORSS
|
||||
end
|
||||
|
||||
def make_channel(content=nil)
|
||||
<<-EOC
|
||||
<channel rdf:about="#{RDF_ABOUT}">
|
||||
<title>#{TITLE_VALUE}</title>
|
||||
<link>#{LINK_VALUE}</link>
|
||||
<description>#{DESCRIPTION_VALUE}</description>
|
||||
|
||||
<image rdf:resource="#{RDF_RESOURCE}" />
|
||||
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
#{RESOURCES.collect do |res| '<rdf:li resource="' + res + '" />' end.join("\n")}
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
|
||||
<textinput rdf:resource="#{RDF_RESOURCE}" />
|
||||
|
||||
#{block_given? ? yield : content}
|
||||
</channel>
|
||||
EOC
|
||||
end
|
||||
|
||||
def make_image(content=nil)
|
||||
<<-EOI
|
||||
<image rdf:about="#{RDF_ABOUT}">
|
||||
<title>#{TITLE_VALUE}</title>
|
||||
<url>#{URL_VALUE}</url>
|
||||
<link>#{LINK_VALUE}</link>
|
||||
#{block_given? ? yield : content}
|
||||
</image>
|
||||
EOI
|
||||
end
|
||||
|
||||
def make_item(content=nil)
|
||||
<<-EOI
|
||||
<item rdf:about="#{RDF_ABOUT}">
|
||||
<title>#{TITLE_VALUE}</title>
|
||||
<link>#{LINK_VALUE}</link>
|
||||
<description>#{DESCRIPTION_VALUE}</description>
|
||||
#{block_given? ? yield : content}
|
||||
</item>
|
||||
EOI
|
||||
end
|
||||
|
||||
def make_textinput(content=nil)
|
||||
<<-EOT
|
||||
<textinput rdf:about="#{RDF_ABOUT}">
|
||||
<title>#{TITLE_VALUE}</title>
|
||||
<description>#{DESCRIPTION_VALUE}</description>
|
||||
<name>#{NAME_VALUE}</name>
|
||||
<link>#{LINK_VALUE}</link>
|
||||
#{block_given? ? yield : content}
|
||||
</textinput>
|
||||
EOT
|
||||
end
|
||||
end
|
17
test/rss/each_parser.rb
Normal file
17
test/rss/each_parser.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require "rbconfig"
|
||||
|
||||
c = Config::CONFIG
|
||||
ruby = File.join(c['bindir'], c['ruby_install_name'])
|
||||
|
||||
module RSS
|
||||
AVAILABLE_PARSERS = [ARGV.shift]
|
||||
end
|
||||
|
||||
def load_test_file(name)
|
||||
puts "Loading #{name} ..."
|
||||
require name
|
||||
end
|
||||
|
||||
load_test_file(ARGV.shift)
|
89
test/rss/my-assertions.rb
Normal file
89
test/rss/my-assertions.rb
Normal file
|
@ -0,0 +1,89 @@
|
|||
module Test
|
||||
module Unit
|
||||
module Assertions
|
||||
|
||||
def assert_parse(rss, assert_method, *args)
|
||||
send("assert_#{assert_method}", *args) do
|
||||
::RSS::Parser.parse(rss)
|
||||
end
|
||||
send("assert_#{assert_method}", *args) do
|
||||
::RSS::Parser.parse(rss, false).validate
|
||||
end
|
||||
end
|
||||
|
||||
def assert_ns(prefix, uri)
|
||||
_wrap_assertion do
|
||||
begin
|
||||
yield
|
||||
flunk("Not raise NSError")
|
||||
rescue ::RSS::NSError => e
|
||||
assert_equal(prefix, e.prefix)
|
||||
assert_equal(uri, e.uri)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_missing_tag(tag, parent)
|
||||
_wrap_assertion do
|
||||
begin
|
||||
yield
|
||||
flunk("Not raise MissingTagError")
|
||||
rescue ::RSS::MissingTagError => e
|
||||
assert_equal(tag, e.tag)
|
||||
assert_equal(parent, e.parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_too_much_tag(tag, parent)
|
||||
_wrap_assertion do
|
||||
begin
|
||||
yield
|
||||
flunk("Not raise TooMuchTagError")
|
||||
rescue ::RSS::TooMuchTagError => e
|
||||
assert_equal(tag, e.tag)
|
||||
assert_equal(parent, e.parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_missing_attribute(tag, attrname)
|
||||
_wrap_assertion do
|
||||
begin
|
||||
yield
|
||||
flunk("Not raise MissingAttributeError")
|
||||
rescue ::RSS::MissingAttributeError => e
|
||||
assert_equal(tag, e.tag)
|
||||
assert_equal(attrname, e.attribute)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_not_excepted_tag(tag, parent)
|
||||
_wrap_assertion do
|
||||
begin
|
||||
yield
|
||||
flunk("Not raise NotExceptedTagError")
|
||||
rescue ::RSS::NotExceptedTagError => e
|
||||
assert_equal(tag, e.tag)
|
||||
assert_equal(parent, e.parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_not_available_value(tag, value)
|
||||
_wrap_assertion do
|
||||
begin
|
||||
yield
|
||||
flunk("Not raise NotAvailableValueError")
|
||||
rescue ::RSS::NotAvailableValueError => e
|
||||
assert_equal(tag, e.tag)
|
||||
assert_equal(value, e.value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
16
test/rss/test.rb
Normal file
16
test/rss/test.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require "rbconfig"
|
||||
require "rss/parser"
|
||||
|
||||
c = Config::CONFIG
|
||||
ruby = File.join(c['bindir'], c['ruby_install_name'])
|
||||
|
||||
RSS::AVAILABLE_PARSERS.each do |parser|
|
||||
puts "------------------------------------"
|
||||
puts "Using #{parser}"
|
||||
puts "------------------------------------"
|
||||
Dir.glob(ARGV.shift || "test/test_*") do |file|
|
||||
puts(`#{ruby} #{if $DEBUG then '-d' end} -I. -I./lib test/each_parser.rb #{parser} #{file} #{ARGV.join(' ')}`)
|
||||
end
|
||||
end
|
237
test/rss/test_1.0.rb
Normal file
237
test/rss/test_1.0.rb
Normal file
|
@ -0,0 +1,237 @@
|
|||
require "test/unit"
|
||||
require "rexml/document"
|
||||
|
||||
require "rss/1.0"
|
||||
require "test/common"
|
||||
|
||||
class TestCore < Test::Unit::TestCase
|
||||
|
||||
include TestRSSMixin
|
||||
|
||||
def setup
|
||||
|
||||
@rdf_prefix = "rdf"
|
||||
@rdf_uri = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
@uri = "http://purl.org/rss/1.0/"
|
||||
|
||||
end
|
||||
|
||||
def test_RDF
|
||||
|
||||
version = "1.0"
|
||||
encoding = "UTF-8"
|
||||
standalone = "no"
|
||||
|
||||
rdf = RDF.new(version, encoding, standalone)
|
||||
|
||||
doc = REXML::Document.new(rdf.to_s(false))
|
||||
|
||||
xmldecl = doc.xml_decl
|
||||
|
||||
%w(version encoding standalone).each do |x|
|
||||
assert_equal(instance_eval(x), xmldecl.send(x))
|
||||
end
|
||||
|
||||
assert_equal(@rdf_uri, doc.root.namespace)
|
||||
|
||||
end
|
||||
|
||||
def test_channel
|
||||
|
||||
about = "http://hoge.com"
|
||||
title = "fugafuga"
|
||||
link = "http://hoge.com"
|
||||
description = "fugafugafugafuga"
|
||||
resource = "http://hoge.com/hoge.png"
|
||||
image = RDF::Channel::Image.new(resource)
|
||||
items = RDF::Channel::Items.new
|
||||
textinput = RDF::Channel::Textinput.new(resource)
|
||||
|
||||
channel = RDF::Channel.new(about)
|
||||
%w(title link description image items textinput).each do |x|
|
||||
channel.send("#{x}=", instance_eval(x))
|
||||
end
|
||||
|
||||
doc = REXML::Document.new(make_RDF(channel.to_s))
|
||||
c = doc.root.elements[1]
|
||||
|
||||
assert_equal(about, c.attributes["about"])
|
||||
%w(title link description image textinput).each do |x|
|
||||
elem = c.elements[x]
|
||||
assert_equal(x, elem.name)
|
||||
assert_equal(@uri, elem.namespace)
|
||||
if x == "image" or x == "textinput"
|
||||
excepted = resource
|
||||
res = elem.attributes.get_attribute("resource")
|
||||
assert_equal(@rdf_uri, res.namespace)
|
||||
value = res.value
|
||||
else
|
||||
excepted = instance_eval(x)
|
||||
value = elem.text
|
||||
end
|
||||
assert_equal(excepted, value)
|
||||
end
|
||||
assert_equal(@uri, c.elements["items"].namespace)
|
||||
assert_equal("items", c.elements["items"].name)
|
||||
|
||||
end
|
||||
|
||||
def test_channel_image
|
||||
|
||||
resource = "http://hoge.com/hoge.png"
|
||||
image = RDF::Channel::Image.new(resource)
|
||||
|
||||
doc = REXML::Document.new(make_RDF(image.to_s))
|
||||
i = doc.root.elements[1]
|
||||
|
||||
assert_equal("image", i.name)
|
||||
assert_equal(@uri, i.namespace)
|
||||
|
||||
res = i.attributes.get_attribute("resource")
|
||||
|
||||
assert_equal(@rdf_uri, res.namespace)
|
||||
assert_equal(resource, res.value)
|
||||
|
||||
end
|
||||
|
||||
def test_channel_textinput
|
||||
|
||||
resource = "http://hoge.com/hoge.png"
|
||||
textinput = RDF::Channel::Textinput.new(resource)
|
||||
|
||||
doc = REXML::Document.new(make_RDF(textinput.to_s))
|
||||
t = doc.root.elements[1]
|
||||
|
||||
assert_equal("textinput", t.name)
|
||||
assert_equal(@uri, t.namespace)
|
||||
|
||||
res = t.attributes.get_attribute("resource")
|
||||
|
||||
assert_equal(@rdf_uri, res.namespace)
|
||||
assert_equal(resource, res.value)
|
||||
|
||||
end
|
||||
|
||||
def test_items
|
||||
|
||||
items = RDF::Channel::Items.new
|
||||
|
||||
doc = REXML::Document.new(make_RDF(items.to_s))
|
||||
i = doc.root.elements[1]
|
||||
|
||||
assert_equal("items", i.name)
|
||||
assert_equal(@uri, i.namespace)
|
||||
|
||||
assert_equal(1, i.elements.size)
|
||||
assert_equal("Seq", i.elements[1].name)
|
||||
assert_equal(@rdf_uri, i.elements[1].namespace)
|
||||
|
||||
end
|
||||
|
||||
def test_seq
|
||||
|
||||
seq = RDF::Seq.new
|
||||
|
||||
doc = REXML::Document.new(make_RDF(seq.to_s))
|
||||
s = doc.root.elements[1]
|
||||
|
||||
assert_equal("Seq", s.name)
|
||||
assert_equal(@rdf_uri, s.namespace)
|
||||
|
||||
end
|
||||
|
||||
def test_li
|
||||
|
||||
resource = "http://hoge.com/"
|
||||
li = RDF::Li.new(resource)
|
||||
|
||||
doc = REXML::Document.new(make_RDF(li.to_s))
|
||||
l = doc.root.elements[1]
|
||||
|
||||
assert_equal("li", l.name)
|
||||
assert_equal(@rdf_uri, l.namespace(l.prefix))
|
||||
|
||||
res = l.attributes.get_attribute("resource")
|
||||
|
||||
assert_equal('', res.instance_eval("@prefix"))
|
||||
assert_equal(resource, res.value)
|
||||
|
||||
end
|
||||
|
||||
def test_image
|
||||
|
||||
about = "http://hoge.com"
|
||||
title = "fugafuga"
|
||||
url = "http://hoge.com/hoge"
|
||||
link = "http://hoge.com/fuga"
|
||||
|
||||
image = RDF::Image.new(about)
|
||||
%w(title url link).each do |x|
|
||||
image.send("#{x}=", instance_eval(x))
|
||||
end
|
||||
|
||||
doc = REXML::Document.new(make_RDF(image.to_s))
|
||||
i = doc.root.elements[1]
|
||||
|
||||
assert_equal(about, i.attributes["about"])
|
||||
%w(title url link).each do |x|
|
||||
elem = i.elements[x]
|
||||
assert_equal(x, elem.name)
|
||||
assert_equal(@uri, elem.namespace)
|
||||
assert_equal(instance_eval(x), elem.text)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_item
|
||||
|
||||
about = "http://hoge.com"
|
||||
title = "fugafuga"
|
||||
link = "http://hoge.com/fuga"
|
||||
description = "hogehogehoge"
|
||||
|
||||
item = RDF::Item.new(about)
|
||||
%w(title link description).each do |x|
|
||||
item.send("#{x}=", instance_eval(x))
|
||||
end
|
||||
|
||||
doc = REXML::Document.new(make_RDF(item.to_s))
|
||||
i = doc.root.elements[1]
|
||||
|
||||
assert_equal(about, i.attributes["about"])
|
||||
%w(title link description).each do |x|
|
||||
elem = i.elements[x]
|
||||
assert_equal(x, elem.name)
|
||||
assert_equal(@uri, elem.namespace)
|
||||
assert_equal(instance_eval(x), elem.text)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_textinput
|
||||
|
||||
about = "http://hoge.com"
|
||||
title = "fugafuga"
|
||||
link = "http://hoge.com/fuga"
|
||||
name = "foo"
|
||||
description = "hogehogehoge"
|
||||
|
||||
textinput = RDF::Textinput.new(about)
|
||||
%w(title link name description).each do |x|
|
||||
textinput.send("#{x}=", instance_eval(x))
|
||||
end
|
||||
|
||||
doc = REXML::Document.new(make_RDF(textinput.to_s))
|
||||
t = doc.root.elements[1]
|
||||
|
||||
assert_equal(about, t.attributes["about"])
|
||||
%w(title link name description).each do |x|
|
||||
elem = t.elements[x]
|
||||
assert_equal(x, elem.name)
|
||||
assert_equal(@uri, elem.namespace)
|
||||
assert_equal(instance_eval(x), elem.text)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
24
test/rss/test_accessor.rb
Normal file
24
test/rss/test_accessor.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
require "test/unit"
|
||||
require "rss/parser"
|
||||
require "rss/1.0"
|
||||
require "rss/2.0"
|
||||
require "test/common"
|
||||
|
||||
class TestAccessor < Test::Unit::TestCase
|
||||
include TestRSSMixin
|
||||
|
||||
def test_date
|
||||
channel = Rss::Channel.new
|
||||
channel.do_validate = false
|
||||
channel.pubDate = nil
|
||||
assert_nil(channel.pubDate)
|
||||
|
||||
time = Time.now
|
||||
channel.pubDate = time
|
||||
assert_equal(time, channel.pubDate)
|
||||
|
||||
channel.pubDate = nil
|
||||
assert_nil(channel.pubDate)
|
||||
end
|
||||
|
||||
end
|
94
test/rss/test_content.rb
Normal file
94
test/rss/test_content.rb
Normal file
|
@ -0,0 +1,94 @@
|
|||
require "test/unit"
|
||||
require "cgi-lib"
|
||||
require "rexml/document"
|
||||
|
||||
require "rss/parser"
|
||||
require "rss/content"
|
||||
require "test/common"
|
||||
|
||||
class TestContent < Test::Unit::TestCase
|
||||
include TestRSSMixin
|
||||
|
||||
def setup
|
||||
@prefix = "content"
|
||||
@uri = "http://purl.org/rss/1.0/modules/content/"
|
||||
|
||||
@parents = %w(item)
|
||||
|
||||
@elems = {
|
||||
:encoded => "<em>ATTENTION</em>",
|
||||
}
|
||||
|
||||
@content_nodes = @elems.collect do |name, value|
|
||||
"<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>"
|
||||
end.join("\n")
|
||||
|
||||
@rss_source = make_RDF(<<-EOR, {@prefix => @uri})
|
||||
#{make_channel()}
|
||||
#{make_image()}
|
||||
#{make_item(@content_nodes)}
|
||||
#{make_textinput()}
|
||||
EOR
|
||||
|
||||
@rss = Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
def test_parser
|
||||
|
||||
assert_nothing_raised do
|
||||
Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
@elems.each do |tag, value|
|
||||
assert_too_much_tag(tag.to_s, "item") do
|
||||
Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
|
||||
#{make_channel()}
|
||||
#{make_item(("<" + @prefix + ":" + tag.to_s + ">" +
|
||||
CGI.escapeHTML(value.to_s) +
|
||||
"</" + @prefix + ":" + tag.to_s + ">") * 2)}
|
||||
EOR
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_accessor
|
||||
|
||||
new_value = {
|
||||
:encoded => "<![CDATA[<it>hoge</it>]]>",
|
||||
}
|
||||
|
||||
@elems.each do |name, value|
|
||||
@parents.each do |parent|
|
||||
meth = "#{RSS::CONTENT_PREFIX}_#{name}"
|
||||
assert_equal(value, @rss.send(parent).send(meth))
|
||||
@rss.send(parent).send("#{meth}=", new_value[name].to_s)
|
||||
assert_equal(new_value[name], @rss.send(parent).send(meth))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
|
||||
@elems.each do |name, value|
|
||||
excepted = "<#{@prefix}:#{name}>#{CGI.escapeHTML(value)}</#{@prefix}:#{name}>"
|
||||
@parents.each do |parent|
|
||||
meth = "#{RSS::CONTENT_PREFIX}_#{name}_element"
|
||||
assert_equal(excepted, @rss.send(parent).send(meth))
|
||||
end
|
||||
end
|
||||
|
||||
REXML::Document.new(@rss_source).root.each_element do |parent|
|
||||
if @parents.include?(parent.name)
|
||||
parent.each_element do |elem|
|
||||
if elem.namespace == @uri
|
||||
assert_equal(elem.text, @elems[elem.name.intern].to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
123
test/rss/test_dublincore.rb
Normal file
123
test/rss/test_dublincore.rb
Normal file
|
@ -0,0 +1,123 @@
|
|||
require "test/unit"
|
||||
require "cgi-lib"
|
||||
require "rexml/document"
|
||||
|
||||
require "rss/parser"
|
||||
require "rss/dublincore"
|
||||
require "test/common"
|
||||
|
||||
class TestDublinCore < Test::Unit::TestCase
|
||||
include TestRSSMixin
|
||||
|
||||
def setup
|
||||
@prefix = "dc"
|
||||
@uri = "http://purl.org/dc/elements/1.1/"
|
||||
|
||||
@parents = %w(channel image item textinput)
|
||||
|
||||
t = Time.iso8601("2000-01-01T12:00:05+00:00")
|
||||
class << t
|
||||
alias_method(:to_s, :iso8601)
|
||||
end
|
||||
|
||||
@elems = {
|
||||
:title => "hoge",
|
||||
:description =>
|
||||
" XML is placing increasingly heavy loads on the existing technical
|
||||
infrastructure of the Internet.",
|
||||
:creator => "Rael Dornfest (mailto:rael@oreilly.com)",
|
||||
:subject => "XML",
|
||||
:publisher => "The O'Reilly Network",
|
||||
:contributor => "hogehoge",
|
||||
:type => "fugafuga",
|
||||
:format => "hohoho",
|
||||
:identifier => "fufufu",
|
||||
:source => "barbar",
|
||||
:language => "ja",
|
||||
:relation => "cococo",
|
||||
:rights => "Copyright (c) 2000 O'Reilly & Associates, Inc.",
|
||||
:date => t,
|
||||
}
|
||||
|
||||
@dc_nodes = @elems.collect do |name, value|
|
||||
"<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>"
|
||||
end.join("\n")
|
||||
|
||||
@rss_source = make_RDF(<<-EOR, {@prefix => @uri})
|
||||
#{make_channel(@dc_nodes)}
|
||||
#{make_image(@dc_nodes)}
|
||||
#{make_item(@dc_nodes)}
|
||||
#{make_textinput(@dc_nodes)}
|
||||
EOR
|
||||
|
||||
@rss = Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
def test_parser
|
||||
|
||||
assert_nothing_raised do
|
||||
Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
@elems.each do |tag, value|
|
||||
assert_too_much_tag(tag.to_s, "channel") do
|
||||
Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
|
||||
#{make_channel(("<" + @prefix + ":" + tag.to_s + ">" +
|
||||
value.to_s +
|
||||
"</" + @prefix + ":" + tag.to_s + ">") * 2)}
|
||||
#{make_item}
|
||||
EOR
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_accessor
|
||||
|
||||
new_value = "hoge"
|
||||
|
||||
@elems.each do |name, value|
|
||||
@parents.each do |parent|
|
||||
parsed_value = @rss.send(parent).send("dc_#{name}")
|
||||
if parsed_value.kind_of?(String)
|
||||
parsed_value = CGI.escapeHTML(parsed_value)
|
||||
end
|
||||
assert_equal(value, parsed_value)
|
||||
if name == :date
|
||||
t = Time.iso8601("2003-01-01T02:30:23+09:00")
|
||||
class << t
|
||||
alias_method(:to_s, :iso8601)
|
||||
end
|
||||
@rss.send(parent).send("dc_#{name}=", t.iso8601)
|
||||
assert_equal(t, @rss.send(parent).send("dc_#{name}"))
|
||||
else
|
||||
@rss.send(parent).send("dc_#{name}=", new_value)
|
||||
assert_equal(new_value, @rss.send(parent).send("dc_#{name}"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
|
||||
@elems.each do |name, value|
|
||||
excepted = "<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>"
|
||||
@parents.each do |parent|
|
||||
assert_equal(excepted, @rss.send(parent).send("dc_#{name}_element"))
|
||||
end
|
||||
end
|
||||
|
||||
REXML::Document.new(@rss_source).root.each_element do |parent|
|
||||
if @parents.include?(parent.name)
|
||||
parent.each_element do |elem|
|
||||
if elem.namespace == @uri
|
||||
assert_equal(CGI.escapeHTML(elem.text), @elems[elem.name.intern].to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
418
test/rss/test_parser.rb
Normal file
418
test/rss/test_parser.rb
Normal file
|
@ -0,0 +1,418 @@
|
|||
require "test/unit"
|
||||
require "rss/parser"
|
||||
require "rss/1.0"
|
||||
require "test/common"
|
||||
|
||||
class TestParser < Test::Unit::TestCase
|
||||
include TestRSSMixin
|
||||
|
||||
def test_RDF
|
||||
assert_ns("", RDF::URI) do
|
||||
Parser.parse(<<-EOR)
|
||||
#{make_xmldecl}
|
||||
<RDF/>
|
||||
EOR
|
||||
end
|
||||
|
||||
assert_ns("", RDF::URI) do
|
||||
Parser.parse(<<-EOR)
|
||||
#{make_xmldecl}
|
||||
<RDF xmlns="hoge"/>
|
||||
EOR
|
||||
end
|
||||
|
||||
assert_ns("rdf", RDF::URI) do
|
||||
Parser.parse(<<-EOR)
|
||||
#{make_xmldecl}
|
||||
<rdf:RDF xmlns:rdf="hoge"/>
|
||||
EOR
|
||||
end
|
||||
|
||||
assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
|
||||
#{make_xmldecl}
|
||||
<rdf:RDF xmlns:rdf="#{RSS::RDF::URI}"/>
|
||||
EOR
|
||||
|
||||
assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
|
||||
#{make_xmldecl}
|
||||
<RDF xmlns="#{RSS::RDF::URI}"/>
|
||||
EOR
|
||||
|
||||
assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
|
||||
#{make_xmldecl}
|
||||
<RDF xmlns="#{RSS::RDF::URI}"/>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
|
||||
#{make_channel}
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
|
||||
#{make_channel}
|
||||
#{make_textinput}
|
||||
EOR
|
||||
|
||||
assert_too_much_tag("image", "RDF") do
|
||||
Parser.parse(make_RDF(<<-EOR))
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
#{make_textinput}
|
||||
EOR
|
||||
end
|
||||
|
||||
assert_not_excepted_tag("image", "RDF") do
|
||||
Parser.parse(make_RDF(<<-EOR))
|
||||
#{make_channel}
|
||||
#{make_item}
|
||||
#{make_image}
|
||||
#{make_textinput}
|
||||
EOR
|
||||
end
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
#{make_textinput}
|
||||
EOR
|
||||
|
||||
1.step(15, 3) do |i|
|
||||
rss = make_RDF() do
|
||||
res = make_channel
|
||||
i.times { res << make_item }
|
||||
res
|
||||
end
|
||||
assert_parse(rss, :nothing_raised)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_channel
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_attribute, "channel", "about")
|
||||
<channel />
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "channel")
|
||||
<channel rdf:about="http://example.com/"/>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "channel")
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<EOR), :missing_tag, "description", "channel")
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "items", "channel")
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
<description>hogehoge</description>
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_attribute, "image", "resource")
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
<description>hogehoge</description>
|
||||
<image/>
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "items", "channel")
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
<description>hogehoge</description>
|
||||
<image rdf:resource="http://example.com/hoge.png" />
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
rss = make_RDF(<<-EOR)
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
<description>hogehoge</description>
|
||||
<image rdf:resource="http://example.com/hoge.png" />
|
||||
<items/>
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
assert_missing_tag("Seq", "items") do
|
||||
Parser.parse(rss)
|
||||
end
|
||||
|
||||
assert_missing_tag("item", "RDF") do
|
||||
Parser.parse(rss, false).validate
|
||||
end
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
<description>hogehoge</description>
|
||||
<image rdf:resource="http://example.com/hoge.png" />
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_attribute, "textinput", "resource")
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
<description>hogehoge</description>
|
||||
<image rdf:resource="http://example.com/hoge.png" />
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
<textinput/>
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
|
||||
<channel rdf:about="http://example.com/">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
<description>hogehoge</description>
|
||||
<image rdf:resource="http://example.com/hoge.png" />
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
<textinput rdf:resource="http://example.com/search" />
|
||||
</channel>
|
||||
EOR
|
||||
|
||||
end
|
||||
|
||||
def test_image
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_attribute, "image", "about")
|
||||
#{make_channel}
|
||||
<image>
|
||||
</image>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "image")
|
||||
#{make_channel}
|
||||
<image rdf:about="http://example.com/hoge.png">
|
||||
</image>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "url", "image")
|
||||
#{make_channel}
|
||||
<image rdf:about="http://example.com/hoge.png">
|
||||
<title>hoge</title>
|
||||
</image>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "image")
|
||||
#{make_channel}
|
||||
<image rdf:about="http://example.com/hoge.png">
|
||||
<title>hoge</title>
|
||||
<url>http://example.com/hoge.png</url>
|
||||
</image>
|
||||
EOR
|
||||
|
||||
rss = make_RDF(<<-EOR)
|
||||
#{make_channel}
|
||||
<image rdf:about="http://example.com/hoge.png">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/</link>
|
||||
<url>http://example.com/hoge.png</url>
|
||||
</image>
|
||||
EOR
|
||||
|
||||
assert_missing_tag("url", "image") do
|
||||
Parser.parse(rss)
|
||||
end
|
||||
|
||||
assert_missing_tag("item", "RDF") do
|
||||
Parser.parse(rss, false).validate
|
||||
end
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
|
||||
#{make_channel}
|
||||
<image rdf:about="http://example.com/hoge.png">
|
||||
<title>hoge</title>
|
||||
<url>http://example.com/hoge.png</url>
|
||||
<link>http://example.com/</link>
|
||||
</image>
|
||||
EOR
|
||||
|
||||
end
|
||||
|
||||
def test_item
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_attribute, "item", "about")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
<item>
|
||||
</item>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "item")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
<item rdf:about="http://example.com/hoge.html">
|
||||
</item>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "item")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
<item rdf:about="http://example.com/hoge.html">
|
||||
<title>hoge</title>
|
||||
</item>
|
||||
EOR
|
||||
|
||||
assert_too_much_tag("title", "item") do
|
||||
Parser.parse(make_RDF(<<-EOR))
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
<item rdf:about="http://example.com/hoge.html">
|
||||
<title>hoge</title>
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/hoge.html</link>
|
||||
</item>
|
||||
EOR
|
||||
end
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
<item rdf:about="http://example.com/hoge.html">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/hoge.html</link>
|
||||
</item>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
<item rdf:about="http://example.com/hoge.html">
|
||||
<title>hoge</title>
|
||||
<link>http://example.com/hoge.html</link>
|
||||
<description>hogehoge</description>
|
||||
</item>
|
||||
EOR
|
||||
|
||||
end
|
||||
|
||||
def test_textinput
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_attribute, "textinput", "about")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
<textinput>
|
||||
</textinput>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "textinput")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
<textinput rdf:about="http://example.com/search.html">
|
||||
</textinput>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "description", "textinput")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
<textinput rdf:about="http://example.com/search.html">
|
||||
<title>hoge</title>
|
||||
</textinput>
|
||||
EOR
|
||||
|
||||
assert_too_much_tag("title", "textinput") do
|
||||
Parser.parse(make_RDF(<<-EOR))
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
<textinput rdf:about="http://example.com/search.html">
|
||||
<title>hoge</title>
|
||||
<title>hoge</title>
|
||||
<description>hogehoge</description>
|
||||
</textinput>
|
||||
EOR
|
||||
end
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "name", "textinput")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
<textinput rdf:about="http://example.com/search.html">
|
||||
<title>hoge</title>
|
||||
<description>hogehoge</description>
|
||||
</textinput>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "textinput")
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
<textinput rdf:about="http://example.com/search.html">
|
||||
<title>hoge</title>
|
||||
<description>hogehoge</description>
|
||||
<name>key</name>
|
||||
</textinput>
|
||||
EOR
|
||||
|
||||
assert_parse(make_RDF(<<-EOR), :nothing_raised)
|
||||
#{make_channel}
|
||||
#{make_image}
|
||||
#{make_item}
|
||||
<textinput rdf:about="http://example.com/search.html">
|
||||
<title>hoge</title>
|
||||
<description>hogehoge</description>
|
||||
<name>key</name>
|
||||
<link>http://example.com/search.html</link>
|
||||
</textinput>
|
||||
EOR
|
||||
|
||||
end
|
||||
|
||||
def test_ignore
|
||||
|
||||
rss = make_RDF(<<-EOR)
|
||||
#{make_channel}
|
||||
#{make_item}
|
||||
<a/>
|
||||
EOR
|
||||
|
||||
assert_parse(rss, :nothing_raised)
|
||||
|
||||
assert_not_excepted_tag("a", "RDF") do
|
||||
Parser.parse(rss, true, false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
122
test/rss/test_syndication.rb
Normal file
122
test/rss/test_syndication.rb
Normal file
|
@ -0,0 +1,122 @@
|
|||
require "test/unit"
|
||||
require "cgi-lib"
|
||||
require "rexml/document"
|
||||
|
||||
require "rss/parser"
|
||||
require "rss/syndication"
|
||||
require "test/common"
|
||||
|
||||
class TestSyndication < Test::Unit::TestCase
|
||||
include TestRSSMixin
|
||||
|
||||
def setup
|
||||
@prefix = "sy"
|
||||
@uri = "http://purl.org/rss/1.0/modules/syndication/"
|
||||
|
||||
@parents = %w(channel)
|
||||
|
||||
t = Time.iso8601("2000-01-01T12:00:05+00:00")
|
||||
class << t
|
||||
alias_method(:to_s, :iso8601)
|
||||
end
|
||||
|
||||
@elems = {
|
||||
:updatePeriod => "hourly",
|
||||
:updateFrequency => 2,
|
||||
:updateBase => t,
|
||||
}
|
||||
|
||||
@sy_nodes = @elems.collect do |name, value|
|
||||
"<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>"
|
||||
end.join("\n")
|
||||
|
||||
@rss_source = make_RDF(<<-EOR, {@prefix => @uri})
|
||||
#{make_channel(@sy_nodes)}
|
||||
#{make_image()}
|
||||
#{make_item()}
|
||||
#{make_textinput()}
|
||||
EOR
|
||||
|
||||
@rss = Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
def test_parser
|
||||
|
||||
assert_nothing_raised do
|
||||
Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
@elems.each do |tag, value|
|
||||
assert_too_much_tag(tag.to_s, "channel") do
|
||||
Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
|
||||
#{make_channel(("<" + @prefix + ":" + tag.to_s + ">" +
|
||||
CGI.escapeHTML(value.to_s) +
|
||||
"</" + @prefix + ":" + tag.to_s + ">") * 2)}
|
||||
#{make_item}
|
||||
EOR
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_accessor
|
||||
|
||||
t = Time.iso8601("2003-01-01T12:00:23+09:00")
|
||||
class << t
|
||||
alias_method(:to_s, :iso8601)
|
||||
end
|
||||
|
||||
new_value = {
|
||||
:updatePeriod => "daily",
|
||||
:updateFrequency => +11,
|
||||
:updateBase => t,
|
||||
}
|
||||
|
||||
@elems.each do |name, value|
|
||||
@parents.each do |parent|
|
||||
assert_equal(value, @rss.send(parent).send("sy_#{name}"))
|
||||
@rss.send(parent).send("sy_#{name}=", new_value[name].to_s)
|
||||
assert_equal(new_value[name], @rss.send(parent).send("sy_#{name}"))
|
||||
end
|
||||
end
|
||||
|
||||
%w(hourly daily weekly monthly yearly).each do |x|
|
||||
@parents.each do |parent|
|
||||
assert_nothing_raised do
|
||||
@rss.send(parent).sy_updatePeriod = x
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%w(-2 0.3 -0.4).each do |x|
|
||||
@parents.each do |parent|
|
||||
assert_not_available_value("updateBase", x) do
|
||||
@rss.send(parent).sy_updateBase = x
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
|
||||
@elems.each do |name, value|
|
||||
excepted = "<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>"
|
||||
@parents.each do |parent|
|
||||
assert_equal(excepted, @rss.send(parent).send("sy_#{name}_element"))
|
||||
end
|
||||
end
|
||||
|
||||
REXML::Document.new(@rss_source).root.each_element do |parent|
|
||||
if @parents.include?(parent.name)
|
||||
parent.each_element do |elem|
|
||||
if elem.namespace == @uri
|
||||
assert_equal(elem.text, @elems[elem.name.intern].to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
110
test/rss/test_trackback.rb
Normal file
110
test/rss/test_trackback.rb
Normal file
|
@ -0,0 +1,110 @@
|
|||
require "test/unit"
|
||||
require "cgi-lib"
|
||||
require "rexml/document"
|
||||
|
||||
require "rss/parser"
|
||||
require "rss/trackback"
|
||||
require "test/common"
|
||||
|
||||
class TestTrackBack < Test::Unit::TestCase
|
||||
include TestRSSMixin
|
||||
|
||||
def setup
|
||||
@prefix = "trackback"
|
||||
@uri = "http://madskills.com/public/xml/rss/module/trackback/"
|
||||
|
||||
@parents = %w(item)
|
||||
|
||||
@elems = {
|
||||
:ping => "http://bar.com/tb.cgi?tb_id=rssplustrackback",
|
||||
:about => "http://foo.com/trackback/tb.cgi?tb_id=20020923",
|
||||
}
|
||||
|
||||
@content_nodes = @elems.collect do |name, value|
|
||||
"<#{@prefix}:#{name} rdf:resource=\"#{CGI.escapeHTML(value.to_s)}\"/>"
|
||||
end.join("\n")
|
||||
|
||||
@rss_source = make_RDF(<<-EOR, {@prefix => @uri})
|
||||
#{make_channel()}
|
||||
#{make_image()}
|
||||
#{make_item(@content_nodes)}
|
||||
#{make_textinput()}
|
||||
EOR
|
||||
|
||||
@rss = Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
def test_parser
|
||||
|
||||
assert_nothing_raised do
|
||||
Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
@elems.find_all{|k, v| k == :ping}.each do |tag, value|
|
||||
assert_too_much_tag(tag.to_s, "item") do
|
||||
Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
|
||||
#{make_channel()}
|
||||
#{make_item(("<" + @prefix + ":" + tag.to_s + " rdf:resource=\"" +
|
||||
CGI.escapeHTML(value.to_s) +
|
||||
"\"/>") * 2)}
|
||||
EOR
|
||||
end
|
||||
end
|
||||
|
||||
@elems.find_all{|k, v| k == :about}.each do |tag, value|
|
||||
assert_missing_tag("trackback:ping", "item") do
|
||||
Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
|
||||
#{make_channel()}
|
||||
#{make_item(("<" + @prefix + ":" + tag.to_s + " rdf:resource=\"" +
|
||||
CGI.escapeHTML(value.to_s) +
|
||||
"\"/>") * 2)}
|
||||
EOR
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_accessor
|
||||
|
||||
new_value = {
|
||||
:ping => "http://baz.com/trackback/tb.cgi?tb_id=20030808",
|
||||
:about => "http://hoge.com/trackback/tb.cgi?tb_id=90030808",
|
||||
}
|
||||
|
||||
@elems.each do |name, value|
|
||||
@parents.each do |parent|
|
||||
elem = @rss.send(parent).send("#{RSS::TRACKBACK_PREFIX}_#{name}")
|
||||
meth = "resource"
|
||||
assert_equal(value, elem.send(meth))
|
||||
elem.send("#{meth}=", new_value[name].to_s)
|
||||
assert_equal(new_value[name], elem.send(meth))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
|
||||
@elems.each do |name, value|
|
||||
excepted = %Q!<#{@prefix}:#{name} rdf:resource="#{CGI.escapeHTML(value)}"/>!
|
||||
@parents.each do |parent|
|
||||
meth = "#{RSS::TRACKBACK_PREFIX}_#{name}_element"
|
||||
meth << "s" if name == :about
|
||||
assert_equal(excepted, @rss.send(parent).send(meth))
|
||||
end
|
||||
end
|
||||
|
||||
REXML::Document.new(@rss_source).root.each_element do |parent|
|
||||
if @parents.include?(parent.name)
|
||||
parent.each_element do |elem|
|
||||
if elem.namespace == @uri
|
||||
assert_equal(elem.attributes["resource"], @elems[elem.name.intern])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Add table
Reference in a new issue