0

I need to display some of the elements within an XML feed (SOAP) as HTML. I don't want to store it in the database, but rather, just hit the API each time the data is needed.

I have been able to do this in a rudimentary way with the Feed Me plug-in, but I can tell that, given how the data is nested, and that I don't need all of it, I need a more robust approach. Here is the start of how the data looks. This file goes on for quite a while.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
  <ns2:GetStudentsResponse xmlns:ns2="http://whatever.com" xmlns="http://whatever.com">
     <student>
        <personAttributes>
           <emplid>394837</emplid>
           <pvi>AB94309</pvi>
           <name>
              <first>Dorothy</first>
              <middle>X</middle>
              <last>Liu</last>
           </name>

           etc...
2
  • Just to clarify – you're getting data from an external API as XML and want to output it on a page as HTML? What part of that workflow is/isn't working, what are you having trouble with? What are you using the Feed Me plugin for?
    – MoritzLost
    Sep 7 at 16:07
  • That is correct. Given that the data is nested many levels deep, and I need to get some of it selectively, I'm not sure how to do that. For example, it's not clear to me how to a) check whether a node in the Twig array exists, and b) display it conditionally. BTW, if I use {{ dd(myvar) }} I can see the array. I'm also wondering whether using Feed Me will give me enough flexibility, or if I need to leverage a different tool.
    – 4midori
    Sep 7 at 17:52
1
+150

Still not quite sure I understand the problem completely, but here are some ideas to get you started. Your workflow requires three steps:

  1. Fetch the XML data from the external API.
  2. Parse the XML (the SOAP namespace may require some attention) into a usable format.
  3. Filter and display the parsed data in your template.

I assume your existing code is based on this example for using feeds in your template? In this case, the feed me plugin does steps 1 & 2 for you, at least to a degree. The documentation doesn't actually mention if the plugin is capable of handling SOAP documents, but since you mentioned that part is working, I'll assume it does. If it doesn't, you can also bypass the plugin and use PHP's SoapClient directly, though that might be a bit tedious.

With Feed Me, you have to figure out what the primary element in the XML result is. You will need to make sure the document has a consistent format at least to that degree. Based on your example, the primary element is probably the student node. So the code would look something like this:

{% set params = {
    url: 'http://path.to/feed/',
    type: 'xml',
    element: 'student',
    cache: 60,
} %}

{% set feed = craft.feedme.feed(params) %}

Now all that remains is to loop through the results and display the data. If you're not sure about the fields in the XML documents, you can use Twig to check if specific fields are defined and display them:

{% for student in feed %}
    {% if student.studentAttributes is defined %}
        Employee ID: {{ student.studentAttributes.emplid ?? 'No employee ID' }}
        PVI: {{ student.studentAttributes.pvi ?? 'Not found' }}
    {% endif %}
    {# ... #}
{% endfor %}

Hopefully this helps. If you're having trouble with a specific step (displaying fields conditionally, parsing the data with Feed Me, etc) please post the code you're having trouble with, this will make it easier to find what's going wrong.

4
  • thanks, this is very helpful. It seems part of my issue was a very elementary mistake on my part, not related to the feed itself. A related question about accessing the feed, in order to generate this specific SOAP feed, I have to pass it a SOAP-based query, also in XML. How would one do that in Craft?
    – 4midori
    Sep 8 at 14:29
  • @4midori Not sure I understand. Where exactly is this feed coming from, an external API that requires SOAP? In this question, I don't think Craft provides any utilities for SOAP APIs, it's a pretty dated standard after all ... I thought your question indicated that Feed Me already takes care of accessing the feed, or was that a misunderstanding? Anyway, if Feed Me doesn't do this, you'll probably need to do that manually using the SoapClient class or an external library.
    – MoritzLost
    Sep 8 at 14:46
  • That is correct, the feed comes from an external API that requires SOAP. Right now I am using Feed Me on a sample XML document. Basically, I saved the feed's results and am hitting that in that of hitting the feed directly. I don't believe Feed Me can send a SOAP request.
    – 4midori
    Sep 8 at 15:46
  • 1
    @4midori Ok, I see, so Feed Me won't really help you there. I'm not that familiar with SOAP, but the laminas (Zend) library for SOAP looks solid, maybe you could use that? Or maybe just the barebones PHP SOAP module, there are some good comments here which explain how to send SOAP calls with the SoapClient class.
    – MoritzLost
    Sep 9 at 7:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.