2009-08-17 6 views
4

Ich versuche, eine XML-Datei blog.xml als yaml auszugeben, um auf vision.app, ein Tool zum Entwerfen von Shopify-E-Commerce-Sites, zuzugreifen.Konvertieren von XML in Yaml mit Ruby und Hpricot - was läuft hier falsch?

Shopify der yaml sieht wie folgt aus:

- id: 2 
    handle: bigcheese-blog 
    title: Bigcheese blog 
    url: /blogs/bigcheese-blog 
    articles: 
    - id: 1 
     title: 'One thing you probably did not know yet...' 
     author: Justin 
     content: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 
     created_at: 2005-04-04 16:00 
     comments: 
     - 
      id: 1 
      author: John Smith 
      email: [email protected] 
      content: Wow...great article man. 
      status: published 
      created_at: 2009-01-01 12:00 
      updated_at: 2009-02-01 12:00 
      url: "" 
     - 
      id: 2 
      author: John Jones 
      email: [email protected] 
      content: I really enjoyed this article. And I love your shop! It's awesome. Shopify rocks! 
      status: published 
      created_at: 2009-03-01 12:00 
      updated_at: 2009-02-01 12:00 
      url: "http://somesite.com/" 
    - id: 2 
     title: Fascinating 
     author: Tobi 
     content: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 
     created_at: 2005-04-06 12:00 
     comments: 
    articles_count: 2 
    comments_enabled?: true 
    comment_post_url: "" 
    comments_count: 2 
    moderated?: true 

jedoch Probe myXML wie folgt aussieht:

 <article> 
      <author>Rouska Mellor</author> 
      <blog-id type="integer">273932</blog-id> 
      <body>Worn Again are hiring for a new Sales Director. 

     To view the full job description and details of how to apply click &quot;here&quot;:http://antiapathy.org/?page_id=83</body> 
      <body-html>&lt;p&gt;Worn Again are hiring for a new Sales Director.&lt;/p&gt; 
     &lt;p&gt;To view the full job description and details of how to apply click &lt;a href=&quot;http://antiapathy.org/?page_id=83&quot;&gt;here&lt;/a&gt;&lt;/p&gt;</body-html> 
      <created-at type="datetime">2009-07-29T13:58:59+01:00</created-at> 
      <id type="integer">1179072</id> 
      <published-at type="datetime">2009-07-29T13:58:59+01:00</published-at> 
      <title>Worn Again are hiring!</title> 
      <updated-at type="datetime">2009-07-29T13:59:40+01:00</updated-at> 
     </article> 
     <article> 

ich naiverweise von einem serialisierte Datenformat in ein anderes umgewandelt angenommen recht einfach war, und ich konnte tun Sie einfach dies:

>> require 'hpricot' 
=> true 
>> b = Hpricot.XML(open('blogs.xml')) 
>> puts b.to_yaml 

Aber ich bekomme diese erro r.

NoMethodError: undefined method `yaml_tag_subclasses?' for Hpricot::Doc:Class 
    from /usr/local/lib/ruby/1.8/yaml/tag.rb:69:in `taguri' 
    from /usr/local/lib/ruby/1.8/yaml/rubytypes.rb:16:in `to_yaml' 
    from /usr/local/lib/ruby/1.8/yaml.rb:391:in `call' 
    from /usr/local/lib/ruby/1.8/yaml.rb:391:in `emit' 
    from /usr/local/lib/ruby/1.8/yaml.rb:391:in `quick_emit' 
    from /usr/local/lib/ruby/1.8/yaml/rubytypes.rb:15:in `to_yaml' 
    from /usr/local/lib/ruby/1.8/yaml.rb:117:in `dump' 
    from /usr/local/lib/ruby/1.8/yaml.rb:432:in `y' 
    from (irb):6 
    from :0 
>> 

Wie kann ich die Datenausgabe in der oben genannten Form erhalten? Ich habe versucht, den 'yaml' Edelstein zu importieren, denkend, dass ich einige dieser Methoden vermisse, aber das hat auch nicht geholfen:

+2

epochwolf eröffnet dieses Problem auf GitHub vor einem Monat: http://github.com/why/hpricot/issues/#issue/16 Sind Ihre Spezifikationen die gleiche (Hpricot 0.8.1, Rails 2.3.2, Rubin 1.8.6 (OSX), RubyGems 1.3.4)? – mcandre

+0

Ja, fast: RubyGems - 1.3.5 Rubin 1.8.6 Hpricot 0.8.1 OS X Rails 2.3.2 –

+0

Nur als Hinweis für alle, die nach XML/HTML-Parsing suchen, wird Hpricot nicht mehr verwendet und der Defacto-Standard ist [Nokogiri] (http://nokogiri.org). Das YAML-Parsing ist in Ruby mit der Klasse [YAML] (http://www.ruby-doc.org/stdlib-2.1.5/libdoc/yaml/rdoc/index.html) integriert. –

Antwort

1

Entschuldigung, Josh, ich denke, was Sie hier gefunden haben, ist eine Einschränkung in den Hpricot und/oder den YAML-Bibliotheken, ganz einfach.

Ich bin nicht sicher, ob Hpricot jemals YAML auf diese Weise unterstützt. Die fragliche Methode wird dynamisch von der YAML-Bibliothek zur Object-Klasse hinzugefügt, ebenso wie andere fundamentale Ruby-Typen, wird aber aus irgendeinem Grund nicht in der Hpricot :: Doc-Definition angezeigt, obwohl Hpricot :: Doc scheinbar erbt indirekt von Object.

Ich kann sagen, dass ich es auch reproduziert habe, also sind es nicht nur Sie.

Sie können sehr leicht die fehlende Methode hinzufügen:

class Hpricot::Doc 
    def self.yaml_tag_subclasses? 
    "true" 
    end 
end 
b = Hpricot.XML(open('blogs.xml')) 

aber Sie werden feststellen, dass nicht findet man viel weiter erhalten. Hier ist, was ich bekomme:

--- !ruby/object:Hpricot::Doc 
options: 
    :xml: true 

Also sind wir nicht über den Container wie wir sollten.

An diesem Punkt, um YAML-Unterstützung mit der YAML-Bibliothek zu erhalten, wäre der Brute-Force-Weg (vielleicht der einzige Weg) to_yaml Methoden zu Hpricots Klassen hinzuzufügen, um ihnen beizubringen, wie YAML korrekt ausgegeben wird. Sehen Sie sich "/usr/lib/ruby/1.8/yaml/rubytypes.rb" an (auf einem Mac wäre das etwa "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib" /ruby/1.8/yaml/rubytypes.rb ") für Beispiele, wie das für jeden der grundlegenden Ruby-Typen gemacht wird. Die Klassen, zu denen Sie möglicherweise hinzufügen müssen, sind auf der C-Seite definiert: siehe "hpricot/ext/hpricot_scan/hpricot_scan.rl" in der Methode Init_hpricot_scan.