Ruby 객체를 XML로 변환하기 위해 nokogiri-happymapper 와 roxml 을 사용하기 시작했습니다 . 들여 쓰기 ( "\ n") 및 지침없이 XML을 생성 할 수 없습니다.
nokogiri-happymapper 및 roxml에서 Active Support 에 대해 설정 :indent=>0, :skip_instruct
한 to_xml
것처럼 메서드에 대해 설정할 옵션이 있습니까?
내가 사용하여 객체에 XML로 변환 할 때 또한, roxml을 , 내가 포함 된 문자열을 얻을 @roxml_references
. XML을 Ruby 객체로 올바르게 변환하려면 어떻게해야합니까?
ROXML 코드는 다음과 같습니다.
require 'roxml'
class Book
include ROXML
xml_accessor :isbn
xml_accessor :title
xml_accessor :description
xml_accessor :author
end
book = Book.new
book.author = "ABC"
book.title = "Ruby"
doc = Nokogiri::XML::Document.new
doc.root = book.to_xml
puts doc.to_s
다음을 출력합니다.
"<?xml version=\"1.0\"?>\n<book>\n <title>Ruby</title>\n <author>ABC</author>\n</book>\n"
과:
obj = Book.from_xml(doc.to_s)
puts obj
다음을 출력합니다.
#<Mod::Book:0x00000003141718 @author="ABC", @title="Ruby", @roxml_references=[#<ROXML::XMLTextRef:0x00000003141650 @opts=#<ROXML::Definition
:0x000000031b93f8 @default=nil, @to_xml=nil, @name_explicit=false, @cdata=nil, @required=nil, @frozen=nil, @wrapper=nil, @namespace=nil, @ac
cessor="isbn", @array=false, @blocks=[], @sought_type=:text, @attr_name="isbn", @name="isbn">, @instance=#<Mod::Book:0x00000003141718 ...>,
@default_namespace=nil>, #<ROXML::XMLTextRef:0x00000003141628 @opts=#<ROXML::Definition:0x000000031b8930 @default=nil, @to_xml=nil, @name_ex
plicit=false, @cdata=nil, @required=nil, @frozen=nil, @wrapper=nil, @namespace=nil, @accessor="title", @array=false, @blocks=[], @sought_typ
e=:text, @attr_name="title", @name="title">, @instance=#<Mod::Book:0x00000003141718 ...>, @default_namespace=nil>, #<ROXML::XMLTextRef:0x000
00003141600 @opts=#<ROXML::Definition:0x000000031a3fa8 @default=nil, @to_xml=nil, @name_explicit=false, @cdata=nil, @required=nil, @frozen=n
il, @wrapper=nil,
nokogiri-happymapper 코드는 다음과 같습니다.
require 'happymapper'
class Book
include HappyMapper
attr_accessor :title,:author
tag 'book'
element :title, String, :tag => 'title'
element :author, String, :tag => 'author'
end
book = Mod::Book.new
book.author = "ABC"
book.title = "Ruby"
xml_obj = book.to_xml
p xml_obj
다음을 출력합니다.
"<?xml version=\"1.0\"?>\n<book>\n <title>Ruby</title>\n <author>ABC</author>\n</book>\n"
과:
obj = Mod::Book.parse(xml_obj)
p obj
다음을 출력합니다.
#<Mod::Book:0x00000000661cf0 @author="ABC", @title="Ruby">
객체에서 XML을 생성 할 때 두 접근 방식에 대한 XML 명령과 함께 들여 쓰기를 제거하려면 어떻게해야합니까?
다음과 같은 접근 방식을 시도했습니다. 접근 방식 1 :
xml = Nokogiri::XML(xml_obj).to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
p xml
어느 출력
"<book>\n <title>Ruby</title>\n <author>ABC</author>\n</book>\n"
접근법 2 :
xml = Nokogiri::XML::Document.parse(xml_obj, nil,nil, Nokogiri::XML::ParseOptions::NOBLANKS).root.to_s
p xml
어느 출력
"<book>\n <title>Ruby</title>\n <author>ABC</author>\n</book>"
아래 접근 방식을 사용하여 객체를 roxml에서 xml로 변환하고 있습니다.
xml_obj = lib.to_xml.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML)
p xml_obj
다음을 출력합니다.
"<Library><author><name>Shruti</name></author><book><title>RoR</title></book></Library>"
이제 xml을 다시 개체로 변환하려고하면 아래와 같이 추가 인스턴스 변수 @roxml_references가 제공됩니다.
obj = Library.from_xml(xml_obj)
p obj
다음을 출력합니다.
#<Library:0x00000002a1ebc0 @author=#<Author:0x00000002a1c780 @name="Shruti", @roxml_references=[#<ROXML::XMLTextRef:0x00000002a1e1e8 @opts=#
<ROXML::Definition:0x00000002a46418 @default=nil, @to_xml=nil, @name_explicit=false, @cdata=nil, @required=nil, @frozen=nil, @wrapper=nil, @
namespace=nil, @accessor="name", @array=false, @blocks=[], @sought_type=:text, @attr_name="name", @name="name">, @instance=#<Author:0x000000
02a1c780 ...>, @default_namespace=nil>]>, @book=[#<Book:0x00000002a08e60 @title="RoR", @roxml_references=[#<ROXML::XMLTextRef:0x00000002a092
e8 @opts=#<ROXML::Definition:0x00000002a3e8d0 @default=nil, @to_xml=nil, @name_explicit=false, @cdata=nil, @required=nil, @frozen=nil, @wrap
per=nil, @namespace=nil, @accessor="title", @array=false, @blocks=[], @sought_type=:text, @attr_name="title", @name="title">, @instance=#<Bo
ok:0x00000002a08e60 ...>, @default_namespace=nil>, #<ROXML::XMLTextRef:0x00000002a09400 @opts=#<ROXML::Definition:0x00000002a3d6b0 @default=
nil, @to_xml=nil, @name_explicit=false, @cdata=nil, @required=nil, @frozen=nil, @wrapper=nil, @namespace=nil, @accessor="description", @arra
y=false, @blocks=[], @sought_type=:text, @attr_name="description", @name="description">, @instance=#<Book:0x00000002a08e60 ...>, @default_na
mespace=nil>], @description=nil>], @roxml_references=[#<ROXML::XMLObjectRef:0x00000002a1eb20 @opts=#<ROXML::Definition:0x00000002a3c080 @def
ault=nil, @to_xml=nil, @name_explicit=false, @cdata=nil, @required=nil, @frozen=nil, @wrapper=nil, @namespace=nil, @accessor="author", @arra
y=false, @blocks=[], @sought_type=Author, @attr_name="author", @name="author">, @instance=#<Library:0x00000002a1ebc0 ...>, @default_namespac
e=nil>, #<ROXML::XMLObjectRef:0x00000002a1eaf8 @opts=#<ROXML::Definition:0x00000002a373c8 @default=nil, @to_xml=nil, @name_explicit=false, @
cdata=nil, @required=nil, @frozen=nil, @wrapper=nil, @namespace=nil, @accessor="book", @array=true, @blocks=[], @sought_type=Book, @attr_nam
e="book", @name="book">, @instance=#<Library:0x00000002a1ebc0 ...>, @default_namespace=nil>]>
@roxml_references
생성 된 개체에서 제거 할 수있는 방법이 있습니까 ?
문서를 검색하고 gem 작성자와상의 한 후에도 여전히 해결책을 찾을 수 없다면 Nokogiri가 출력을 구문 분석하고 노드를 삭제 한 다음 들여 쓰기없이 다시 출력하도록합니다.
이걸 고려하세요:
require 'nokogiri'
xml = <<EOT
<root>
</root>
EOT
Nokogiri::XML(xml)
# => #<Nokogiri::XML::Document:0x3ffd49419494 name="document" children=[#<Nokogiri::XML::Element:0x3ffd49419084 name="root" children=[#<Nokogiri::XML::Text:0x3ffd49418df0 "\n">]>]>
위의 "\ n"이 포함 된 Nokogiri :: XML :: Text 노드를 확인하십시오. <root>
XML에서 다음 과 같은 라인 끝입니다 .
doc.to_xml # => "<?xml version=\"1.0\"?>\n<root>\n</root>\n"
텍스트 노드를 찾는 방법은 다음과 같습니다.
doc.search('//text()') # => [#<Nokogiri::XML::Text:0x3fff88c18d20 "\n">]
'//text()'
"텍스트 노드에 대한 전체 문서 검색"을 의미하는 XPath 선택기입니다.
DOM을 살펴보고 빈 노드 만 삭제할 수 있습니다.
doc.search('//text()').each do |text_node|
text_node.unlink
end
doc.to_xml # => "<?xml version=\"1.0\"?>\n<root/>\n"
그러나 Nokogiri :: XML :: Text 노드는 후행 라인 끝 이상을 포함 할 수 있으므로 무차별 노드 삭제는 원하는 텍스트도 제거 할 수 있으므로주의해야합니다. 노드의 내용을 삭제하여 비워 둘 수도 있습니다.
xml = <<EOT
<root>
<foo>bar</foo>
</root>
EOT
doc = Nokogiri::XML(xml)
doc.search('//text()') # => [#<Nokogiri::XML::Text:0x3ff77201927c "\n ">, #<Nokogiri::XML::Text:0x3ff772018e80 "bar">, #<Nokogiri::XML::Text:0x3ff772018c14 "\n">]
doc.search('//text()').each do |text_node|
text_node.content = ''
end
doc.to_xml # => "<?xml version=\"1.0\"?>\n<root><foo></foo></root>\n"
그러나 원하는 텍스트 "바"가 삭제 된 것을 확인하십시오. 해결책은 더 선택적인 것입니다.
doc.search('//text()').each do |text_node|
text_node.content = '' if text_node.content.strip.empty?
end
doc.to_xml # => "<?xml version=\"1.0\"?>\n<root><foo>bar</foo></root>\n"
참고 : Nokogiri에는 NOBLANKS
들여 쓰기 노드를 제거하는 데 도움이되도록 설계된 구문 분석 옵션이 포함되어 있지만 " XML_PARSE_NOBLANKS의 예상치 못한 동작 "에 따라 기본 libXML2 라이브러리는 잘못된 DOM이 반환 될 것이라고 생각하는 경우 공백을 무시하지 않습니다.
XMLdecl을 원하지 않는 경우 Nokogiri에게 문서를 DocumentFragment로 구문 분석하도록 지시 할 수 있습니다.
xml = <<EOT
<root>
</root>
EOT
doc = Nokogiri::XML(xml)
doc.to_xml # => "<?xml version=\"1.0\"?>\n<root>\n</root>\n"
doc = Nokogiri::XML::DocumentFragment.parse(xml)
doc.to_xml # => "<root>\n</root>\n"
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다