/ / Parse XML pomocou Nokogiri, ale nedokáže vyriešiť menné priestory - ruby, xml, curl, nokogiri

Parse XML pomocou Nokogiri, ale nedokáže vyriešiť menné priestory - ruby, xml, curl, nokogiri

Mám správu XML a môj skript musí byť schopný analyzovať prvok uzla "AccountStatus". Môj skript funguje správne, ak bol XML zverejnený bez menných priestorov.

Keď som zahrnul pôvodné obory názvov, pri vykonávaní skriptu chýba veľká časť údajov XML Nokogiri::XML(request.body.read).

Tu je vzorka 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

Tu je môj skript:

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

Tu je výstup:

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

odpovede:

1 pre odpoveď č. 1

problémy so zakrivením:

Vyzerá to, že prvý problém, ktorý máte, je vo vašom príkazu na zakrivenie. Poznámka: príkaz zakrivenia určuje a -H ale nezadá hlavičku, a ak sa pokúsim spustiť príkaz zakrivenia, dostanem chybu:

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

Vyzerá to, že úvodzovky spôsobujú neporiadok vášho príkazu. V tomto výčnelku príkaz:

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

... prvý citovaný reťazec je:

"<?xml version="

A potom ako kučera interpretuje všetko poto - kto vie. Tento problém môžete vyriešiť pomocou jednoduchých úvodzoviek okolo exteriéru xml. Ale je to oveľa jednoduchšie umiestniť xml do súboru, potom sa má zvlniť súbor. Ak používate -d možnosť s @, ako toto:

 -d @file_name

curl číta xml zo súboru, ktorého meno je file_name. Tu je príklad:

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

Problémy nokogiri:

Každá detská značka vo vašom xml je súčasťou štandardné namespace; preto pred každým názvom podradenej značky je názov priestoru názvov. Napriek tomu ste to len dal docu: pred prvou značkou vo vašom xpath:

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

docu: musí predchádzať každý názov značky. Upozorňujeme tiež, že namiesto špecifikácie docu priestor názvov, môžete jednoducho použiť xmlns: pred každou značkou vo vašom xpath. A je to oveľa jednoduchšie len napísať:

  xpath = "//xmlns:AccountStatus"

Dodávateľ mi poslal správu XML

Podrobnosti o tom, ako sa to bude robiť, sú dôležité.

Tu je príkaz zakrivenia, ktorý urobí a nahranie súboru:

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

-F znamená POST a nahranie súboru, Lokálne sa xml nachádza v súbore s názvom xml5.xml. Aplikácia sinatra potom môže urobiť toto:

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

Alebo s týmto príkazom zakrivenia:

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

... vaša trasa bude vyzerať takto:

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

Záhlaví typu Content-Type:

Na -d možnosť nastaví hlavičke Content-Type v žiadosti:

To spôsobí curl preniesť údaje na server pomocou typu obsahu aplikácie/x-www-formulár-urlencoded.

Na -F možnosť nastaví hlavičke Content-Type v žiadosti:

To spôsobuje curl na POST údajov pomocou Content-Type multipart/formulár-data