2016-06-26 2 views
1

나는 문장을 해당 품사에 따라 분류하기 위해 engtagger 보석을 사용하고 있습니다. 다음과 같이 내가 얻을 출력은 다음과 같습니다인접한 노드와 간단한 XML 유사 문자열 구문 분석

puts text 
# => "<nnp>My</nnp> <nn>name</nn> <vbz>is</vbz> <nnp>Max</nnp>" 

내가 나에게 배열을 제공하기 위해 보석을 기대했을 것이다,하지만 난 배열에 자신이 강요 할 것 같아요. 나는 결국 얻기 위해 노력하고있어

이 같은 중첩 된 배열 무언가이다 : 나는 노코 기리 (또는 다른 파서 라이브러리)와 함께이 문제를 접근하는 방법을 정말 확실하지 않다 그러나

[["My", "nnp"], ["name", "nn"], ["is", "vbz"], ["Max", "nnp"]] 

. 다음은 내가 시도한 것입니다 :

(byebug) doc = Nokogiri::XML(text) 
#<Nokogiri::XML::Document:0x3fd400286e78 name="document" children=[#<Nokogiri::XML::Element:0x3fd400286900 name="nnp" children=[#<Nokogiri::XML::Text:0x3fd400286464 "My">]>]> 
(byebug) Nokogiri.parse(text) 
#<Nokogiri::XML::Document:0x3fd40028cd50 name="document" children=[#<Nokogiri::XML::Element:0x3fd40028c7d8 name="nnp" children=[#<Nokogiri::XML::Text:0x3fd40028c378 "My">]>]> 

두 가지 다른 Nokogiri 방법을 시도했지만 둘 다 첫 번째 노드 만 보여줍니다. 나머지 노드를 어떻게 얻을 수 있습니까?

또는 engtagger 호출을 통해 배열을 반환 할 수 있습니까? 문서에서 배열을 모든 태그과 함께 반환하는 예제를 찾지 못했습니다. 하나의 특정 종류의 태그가있는 배열 만 있습니다.

+0

아 내가 [https://github.com/reddavis/Part-Of-Speech](https://github있는 방법으로. com/reddavis/Part-Of-Speech)을 사용하여 문장을 구문 분석하고 모든 품사를 배열 형식으로 반환합니다. engtagger 대신에 이것을 사용하려고합니다. –

답변

1

중요한 것은 올바른 형식의 XML에는 루트 노드가 있어야한다는 것입니다. Nokogiri는 근원 노드 (최상위 노드)로 처리되었고 닫혀있을 때 Nokogiri가 XML 문서를 종료한다고 생각 했으므로 첫 번째 노드 만 받았습니다.

Nokogiri::XML("<root>#{text}</root>"). 
    children.first. # get root node 
    children.map { |e| [e.text, e.name] }. # map to what’s needed 
    reject { |e| e.last == 'text' } # filter out garbage 

필터링은 더 의미 정확 하심 :

Nokogiri::XML("<root>#{text}</root>"). 
    children.first. 
    children.reject { |e| Nokogiri::XML::Text === e }. 
    map { |e| [e.text, e.name] } 
+0

이 작업은 무엇입니까? 'children.reject {| e | Nokogiri :: XML :: Text === e}' –

+0

이것은 트리플 이퀄, 일명 대소 문자가 같음 ['Module # ==='] (http://ruby-doc.org/core-2.1.5 /Module.html#method-i-3D-3D-3D). 여기서는'e.is_a? (Nokogiri :: XML :: Text)'와 완전히 동일합니다. 전체 구문은 원치 않는 빈 텍스트 노드를 필터링합니다. – mudasobwa

1

이 문제는 잘못 조각을 구문 분석하고 있습니다 :

require 'nokogiri' 
doc = Nokogiri::XML.fragment("<nnp>My</nnp> <nn>name</nn> <vbz>is</vbz> <nnp>Max</nnp>") 
doc.to_xml # => "<nnp>My</nnp> <nn>name</nn> <vbz>is</vbz> <nnp>Max</nnp>" 

노코 기리가 유효한 XML을 원하지만, 당신은 그것을 얻을 수 있습니다 fragment을 사용하여 부분 XML 청크를 허용합니다. 그 시점에서

당신은 할 수있어 :

doc.children.each_with_object([]){ |n, a| a << [n.text, n.name] unless n.text? } 
# => [["My", "nnp"], ["name", "nn"], ["is", "vbz"], ["Max", "nnp"]]