2011-07-27 4 views
8

Come fare in modo che Builder non codifichi "śćż" e altri caratteri simili. Quello che voglio è "całość" per essere letteralmente stampato in un documento XML. Esempio:Rails + Builder.Generazione dell'output XML senza entità

xml.instruct! :xml, :version => '1.0', :encoding => 'utf-8' 
xml.Trader(:'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", 
      :'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema") do 
    xml.Informacje do 
    xml.RodzajPaczki 'całość' 
    xml.Program 'mine' 
    xml.WersjaProgramu '1.0' 
    end 
end 

uscita:

<?xml version="1.0" encoding="utf-8"?> 
<Trader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<Informacje> 
    <RodzajPaczki>ca&#322;o&#347;&#263;</RodzajPaczki> 
    <Program>mine</Program> 
    <WersjaProgramu>1.0</WersjaProgramu> 
    </Informacje> 
</Trader> 

ca&#322;o&#347;&#263; dovrebbe essere całość. Ho visto una pseudo soluzione come xml.RodzajPaczki {|t| t << 'całość' } ma non funziona correttamente. Ha superato "całość" sul lato sinistro di un documento.

risposta

9

Ecco cosa sta succedendo. Come sappiamo per impostazione predefinita, Builder sfugge ai caratteri non ASCII come quelli in całość. Hai anche menzionato un modo possibile per risolvere il problema un pò e che è:

xml.RodzajPaczki {|t| t << 'całość' } 

Purtroppo quando si passa un blocco all'elemento RodzajPaczki, Builder presuppone che ci sarà qualche xml interno, in modo che aggiunge una nuova linea e applica il trattino. Naturalmente nel nostro caso non c'è solo testo interno e non XML in modo da ottenere un output sgradevoli come:

<RodzajPaczki> 
całość  </RodzajPaczki> 

C'è un modo semplice e un modo più difficile per risolvere questo problema. Innanzitutto il modo semplice.

Configura Rientro a zero

quindi è possibile utilizzare la correzione dall'alto xml.RodzajPaczki {|t| t << 'całość' } tutto funzionerà come previsto, ma l'uscita non sarà abbastanza stampato, sarà infact essere tutto su una riga:

<?xml version="1.0" encoding="UTF-8"?><Trader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Informacje><RodzajPaczki>całość</RodzajPaczki><Program>mine</Program><WersjaProgramu>1.0</WersjaProgramu></Informacje></Trader> 

È possibile eseguire questa operazione tramite una stampante esterna carina se si desidera formattarla correttamente.

Se si deve semplicemente avere un output piuttosto stampato e non si desidera eseguire l'escape, è necessario applicare un po 'di patch a Builder. Questo è il modo più difficile per risolvere questo problema.

Patching Builder

Abbiamo bisogno di patch al di inizializzazione della nostra XmlMarkup oggetto da aggiungere un'opzione in più :escape. Allo stesso tempo, applichiamo una patch all'oggetto XmlBase per prendere questa nuova opzione come parametro. Per impostazione predefinita, questa nuova opzione è impostata su true, per mantenere il comportamento predefinito. Applichiamo quindi il patch al metodo text! su XmlBase per utilizzare la nostra nuova opzione per decidere se il testo deve essere ignorato.Ecco come si presenta:

module Builder 
    class XmlBase 
    def initialize(indent=0, initial=0, encoding='utf-8', escape=true) 
     @indent = indent 
     @level = initial 
     @encoding = encoding.downcase 
     @escape = escape 
    end 

    def text!(text) 
     if @escape 
     _text(_escape(text)) 
     else 
     _text(text) 
     end 
    end 
    end 

    class XmlMarkup 
    def initialize(options={}) 
     indent = options[:indent] || 0 
     margin = options[:margin] || 0 
     encoding = options[:encoding] || 'utf-8' 
     escape = options[:escape] 
     if escape == nil 
     escape = true 
     end 
     super(indent, margin, encoding, escape) 
     @target = options[:target] || "" 
    end 
    end 
end 

Ora possiamo usare il nostro costruttore di nuova patch nel modo seguente (avviso che quando si costruisce l'oggetto XmlMarkup passiamo nelle nostre nuove :escape opzioni con un valore di false):

xml = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>3, :encoding => 'utf-8', :escape => false) 
xml.instruct! :xml, :version => '1.0', :encoding => 'UTF-8' 
xml.Trader(:'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", :'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema") do 
    xml.Informacje do 
    xml.RodzajPaczki('całość') 
    xml.Program('mine') 
    xml.WersjaProgramu('1.0') 
    end 
end 

L'uscita è il seguente:

<?xml version="1.0" encoding="UTF-8"?> 
<Trader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Informacje> 
     <RodzajPaczki>całość</RodzajPaczki> 
     <Program>mine</Program> 
     <WersjaProgramu>1.0</WersjaProgramu> 
    </Informacje> 
</Trader> 

Come desiderato, il testo non è sfuggito. Si noti che la patch applicherà questo comportamento di non escape a tutto il testo, quindi se si desidera che parte del testo sia non-escape mentre l'altro testo è ancora sfuggito sarà necessario applicare patch a Builder in misura molto maggiore.

+0

Ci scusiamo per il ritardo nella risposta. Risposta molto informativa Grazie. –

+0

È possibile configurare il rientro come zero se sto utilizzando l'oggetto del builder xml nella vista? –

0

Non riesco a replicarlo utilizzando la mia configurazione. Quale versione di ruby ​​/ rails/builder stai usando?

+0

Ruby versione 1.8.7 Enterprise Edition, Rails 2.3.5, builder 2.1 ma non sono sicuro al 100%. Voglio dire che sono senza lavoro ora e ho diversi progetti in binari da mantenere. –

+0

Ok. Ho facilmente replicato lo stesso comportamento con rails 3.0.9 ruby ​​1.9.2 e builder 3.0.0 sulla mia macchina privata. Quindi in Builder c'è un modo per generare letteralmente "całość", non "ca ł o ś ć"? –

0

È possibile emettere "całość" senza problemi (Ruby 1.9.2, Builder 3.0.0). La pagina di manuale http://builder.rubyforge.org/ suggerisce di impostare $KCODE su 'UTF8' (vedere la fine della pagina), ma penso che questo sia per Ruby 1.8. quello che ho nel mio file, è qualcosa di simile:

#!/usr/bin/ruby -wE UTF-8:UTF-8 
# encoding: UTF-8 

require 'builder' 
... 

xml = Builder::XmlMarkup.new(:target => target, :indent => 2) 
xml.instruct! :xml, :version => '1.0', :encoding => 'UTF-8' 
... 
0

Un commento in Rails ticket #1446 indica che questo può essere fissato in Builder 3.0.0. Non ho ancora provato me stesso.