/ / Analisar XML usando o Nokogiri, mas não consegue resolver namespaces - ruby, xml, curl, nokogiri

Analise XML usando o Nokogiri, mas não consegue resolver namespaces - ruby, xml, curl, nokogiri

Eu tenho uma mensagem XML e meu script precisa ser capaz de analisar o elemento de nó "AccountStatus". Meu script funciona corretamente se o XML postado sem namespaces.

Quando incluí os namespaces originais, uma grande quantidade de dados XML estará ausente quando o script for executado Nokogiri::XML(request.body.read).

Aqui está o exemplo XML:

curl -i -H -X POST -d "<?xml version="1.0" encoding="utf-8" ?>
<DocuSignEnvelopeInformation xmlns="http://www.w3.org/2001/XMLSchema">
<EnvelopeStatus>
<RecipientStatuses>
<RecipientStatus>
<Type>Signer</Type>
<CustomFields />
<AccountStatus>Active</AccountStatus>
<RecipientId>ab2bf57b-72b7-48e7-8298-b1c7b56930b9</RecipientId>
</RecipientStatus>
</RecipientStatuses>
</EnvelopeStatus>
</DocuSignEnvelopeInformation>" localhost:4567/shunt?uri=http://requestb.in/1hiag0y1

Aqui está meu script:

require "rubygems"
require "sinatra"
require "uri"
require "nokogiri"
#require "pry"
#require "pp"

post "/shunt" do
puts "hello world"

xmldoc = Nokogiri::XML(request.body.read)
puts xmldoc

xmldoc.xpath("//docu:DocuSignEnvelopeInformation/EnvelopeStatus/RecipientStatuses/RecipientStatus", "docu"=>"http://www.w3.org/2001/XMLSchema").each do |node|
puts node.text
end
end

Aqui está a saída:

hello world
<?xml version="1.0"?>
<DocuSignEnvelopeInformation/>

Respostas:

1 para resposta № 1

Problemas de Curl:

Parece que o primeiro problema que você está tendo é com o seu comando curl. Note, o seu comando curl especifica um -H opção, ainda não especifica um cabeçalho. E se eu tentar executar o comando curl eu recebo um erro:

curl: (6) Couldn"t resolve host "POST"

Parece que as citações estão bagunçando o seu comando. Neste comando curl:

curl -i -X POST -d "<?xml version="1.0" encoding="utf-8" ?> ...

... a primeira string citada é:

"<?xml version="

E então, como curl interpreta tudo depoisisso - quem sabe. Você pode curar esse problema usando aspas simples ao redor do exterior do xml. Mas, é muito mais fácil colocar o xml em um arquivo, depois ter o curl de ler o arquivo. -d opção com um @, como isso:

 -d @file_name

O curl lerá o xml do arquivo cujo nome é file_name. Aqui está um exemplo:

curl -i -X POST -d @./xml_files/xml5.xml http://localhost:4567/shunt

problemas nokogiri:

Cada tag filho no seu xml faz parte do padrão namespace; portanto, cada nome de tag filho é precedido pelo nome do namespace. No entanto, você só coloca docu: na frente da primeira tag no seu xpath:

//docu:DocuSignEnvelopeInformation/EnvelopeStatus/....
^
|
missing namespace name

docu: tem que preceder cada nome da tag. Além disso, observe que, em vez de especificar docu namespace, você pode simplesmente usar xmlns: na frente de todas as tags no seu xpath. E é muito mais simples apenas escrever:

  xpath = "//xmlns:AccountStatus"

O fornecedor me enviou uma mensagem XML

Os detalhes de como isso será feito são importantes.

Aqui está um comando curl que fará um upload de arquivo:

curl -i -F "xmlfile=@xml5.xml" http://localhost:4567/shunt

-F significa POST a upload de arquivo. Localmente, o xml está em um arquivo chamado xml5.xml. Então, seu aplicativo sinatra pode fazer isso:

post "/shunt" do
require "nokogiri"

doc = Nokogiri::XML(
params["xmlfile"][:tempfile].read
)

xpath = "//xmlns:AccountStatus"
target_tag = doc.at_xpath(xpath)
puts target_tag.text
end

Ou, com este comando curl:

curl -i -X POST -d @xml5.xml http://localhost:4567/shunt

... sua rota ficaria assim:

post "/shunt" do
require "nokogiri"

doc = Nokogiri::XML(
request.body.read
)

xpath = "//xmlns:AccountStatus"
target_tag = doc.at_xpath(xpath)
puts target_tag.text
end

Cabeçalhos do tipo de conteúdo:

o -d opção define o cabeçalho Content-Type na solicitação para:

Isso fará com que o curl passe os dados para o servidor usando o aplicativo de tipo de conteúdo / x-www-form-urlencoded.

o -F opção define o cabeçalho Content-Type na solicitação para:

Isso causa ondulação nos dados POST usando os dados de várias partes / formulários do Content-Type