Я использую Nokogiri 1.10.3 и Ruby 2.4.5.
У меня есть несколько сложных текстовых XML-строк для добавления в документ со стандартным композитным заголовком.Я делаю это, используя Builder для создания документа с заголовком, а затем перебираю строки, чтобы добавить их.
При использовании to_xml
возврат каретки и отступы начала строки теряются издокумент, за исключением того, где они появляются в добавленных XML-строках.
Похоже, что только в самих XML-строках содержится "\n
".
Примеры:
Хорошо: Builder без добавления XML-строк.Полученная строка XML имеет возврат каретки и отступы:
xml = Nokogiri::XML::Builder.new(encoding: "utf-8")
xml.Message do
xml.Header do
xml.NumberOne "1"
xml.NumberTwo "2"
end
end ; 0
xml.to_xml
=> "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Message>\n <Header>\n <NumberOne>1</NumberOne>\n <NumberTwo>2</NumberTwo>\n </Header>\n</Message>\n"
Обратите внимание, например, на "\n
" и пробелы между </NumberOne>
и <NumberTwo>
.
Хорошо: Построитель сДобавляемые строки XML, а строки XML не имеют возврата каретки.Результирующая строка XML имеет возврат каретки и отступы:
xml_text1 = "<text>text1</text>"
xml = Nokogiri::XML::Builder.new(encoding: "utf-8")
xml.Message do
xml.Header do
xml.NumberOne "1"
xml.NumberTwo "2"
end
xml << xml_text1
end ; 0
xml.to_xml
=> "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Message>\n <Header>\n <NumberOne>1</NumberOne>\n <NumberTwo>2</NumberTwo>\n </Header>\n <text>text1</text>\n</Message>\n"
Bad: Builder с добавляемыми строками XML, а строки XML do имеют возврат каретки.Результирующая строка XML имеет возврат каретки и отступы, за исключением случаев, когда во вставленных строках XML они были:
xml_text1 = "<text1>text1</text1>\n<text2>text2</text2>"
xml = Nokogiri::XML::Builder.new(encoding: "utf-8")
xml.Message do
xml.Header do
xml.NumberOne "1"
xml.NumberTwo "2"
end
xml << xml_text1
end ; 0
xml.to_xml
=> "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Message><Header><NumberOne>1</NumberOne><NumberTwo>2</NumberTwo></Header><text1>text1</text1>\n<text2>text2</text2></Message>\n"
Обратите внимание, что "\n
" и пробелы были удалены.
Это будетдля содержимого XML допустимо возвращение каретки, поэтому использование gsub
для удаления всех возвратов каретки из строк не будет для меня вариантом, я боюсь.
Есть ли другой способ включитьэти текстовые строки, которые могут не вызвать такую проблему?
Как указывает @igneus, именно наличие любого текста между элементами XML вызывает такое поведение.
В качестве примера:
xml_text1 = "<text1>tex<b> <b>t1</text1> <text2>text2</text2>"
xml = Nokogiri::XML::Builder.new(encoding: "utf-8")
xml.Message do
xml.Header do
xml.NumberOne "1"
xml.NumberTwo "2"
end
xml << xml_text1.gsub(/>\n {0,}</, "><")
end ; 0
xml.to_xml
=> "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Message><Header><NumberOne>1</NumberOne><NumberTwo>2</NumberTwo></Header><text1>tex<b> <b>t1</b></b></text1> <text2>text2</text2></Message>\n"
Фактически, когда текстовая строка преобразуется во фрагмент, мы видим дополнительные Nokogiri::XML::Text
объекты, содержащие пробел, или в предыдущих примерах с "\n
"," \n
"и т. Д.
xml_text1 = "<text1>tex<b> <b>t1</text1> <text2>text2</text2>"
xml = Nokogiri::XML::Builder.new(encoding: "utf-8")
=> #<Nokogiri::XML::DocumentFragment:0x3fff1805bcb4 name="#document-fragment" children=[#<Nokogiri::XML::Element:0x3fff1805b700 name="text1" children=[#<Nokogiri::XML::Text:0x3fff1805a4f4 "tex">, #<Nokogiri::XML::Element:0x3fff1805a3b4 name="b" children=[#<Nokogiri::XML::Text:0x3fff19a93fc8 " ">, #<Nokogiri::XML::Element:0x3fff19a93dac name="b" children=[#<Nokogiri::XML::Text:0x3fff19a93a3c "t1">]>, #<Nokogiri::XML::Text:0x3fff19a93730 " ">, #<Nokogiri::XML::Element:0x3fff19a9358c name="text2" children=[#<Nokogiri::XML::Text:0x3fff19a93258 "text2">]>]>]>]>
Эти элементы не игнорируются to_xml
.
xml.doc.fragment(xml_text1).to_xml(indent: 0)
=> "<text1>tex<b> <b>t1</b> <text2>text2</text2></b></text1>"
Так что приемлемым решением будет нечто, удаляющее теТекстовые элементы?