0

I'm trying to virtualize an XML-based API using WireMock and generate a JSON response using wiremock standalone jar. The requirement is to copy a tag value from the XML request payload to the JSON response using XPath. However, I'm facing issues with the XPath expressions I've tried so far, and I'm not able to get it to work correctly.

Here's a dummy example to illustrate my scenario: Sample Request Payload (XML):

`<Envelope
    xmlns="http://www.example.com/Envelope"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Header>
        <SourceID>SOURCE_ID</SourceID>
        <Timestamp>2024-07-01T16:27:26Z</Timestamp>
    </Header>
    <Body>
        <Record>
            <Metadata>
                <Key>
                    <Name>RequestNumber</Name>
                    <Value>REQ12345</Value>
                </Key>
            </Metadata>
        </Record>
    </Body>
</Envelope>`

Sample Response Payload (JSON):

`{
  "event": {
    "source": "example",
    "type": "example_event",
    "timestamp": "2024-07-01T16:27:26Z",
    "payload": {
      "requestNumber": "REQ12345"
    }
  }
}`

Problem: I'm getting an UncheckedExecutionException in WireMock, indicating an issue with the XPath expression. Despite trying various XPath expressions, the correct value is not being extracted and placed into the JSON response.

Request for Help: Can anyone guide me on the correct way to extract the value from the XML request payload using XPath in WireMock? Any insights or examples would be greatly appreciated.

XPath Expressions I've Tried:

{{{xpath request.body '//Key[Name="RequestNumber"]/Value/text()'}}}

{{{xpath request.body '//*[local-name()="Key"]//*[local-name()="Name" and text()="RequestNumber"]/*[local-name()="Value"]/text()'}}}

{{{xpath request.body '/*[local-name()="Envelope"]/*[local-name()="Body"]/*[local-name()="Record"]/*[local-name()="Metadata"]/*[local-name()="Key"]/*[local-name()="Name"][text()="RequestNumber"]/following-sibling::*[local-name()="Value"]/text()'}}}

1 Answer 1

0

I think you are spot on with some of your xPath expressions. For example, this one should work as far as I can tell - //Key[Name="RequestNumber"]/Value/text(). I think the main issue is the escaping of quotes etc. To make this easier I separated out the response into a separate file and used the assign helper to hold the xpath expression. That way I don't have to worry about all the escaping of quotes etc.

My json stub mapping looks like this:

{
  "request": {
    "url": "/xml-to-json",
    "method": "POST"
  },
  "response": {
    "status": 200,
    "bodyFileName": "response.txt",
    "headers": {
      "Content-Type": "application/json; charset=utf-8"
    },
    "transformers": [
      "response-template"
    ]
  }
}

My response.txt file looks like this


{{#assign 'xpathExpression'}}//Key[Name="RequestNumber"]/Value/text(){{/assign}}
{
  "event": {
    "source": "example",
    "type": "example_event",
    "timestamp": "2024-07-01T16:27:26Z",
    "payload": {
      "requestNumber": "{{xPath request.body xpathExpression}}"
    }
  }
}

Given the request you specified in your question:

<Envelope
        xmlns="http://www.example.com/Envelope"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Header>
        <SourceID>SOURCE_ID</SourceID>
        <Timestamp>2024-07-01T16:27:26Z</Timestamp>
    </Header>
    <Body>
        <Record>
            <Metadata>
                <Key>
                    <Name>RequestNumber</Name>
                    <Value>REQ12345</Value>
                </Key>
            </Metadata>
        </Record>
    </Body>
</Envelope>

You should see a response that looks like the following when you make the request to the stub:

{
  "event": {
    "source": "example",
    "type": "example_event",
    "timestamp": "2024-07-01T16:27:26Z",
    "payload": {
      "requestNumber": "REQ12345"
    }
  }
}

You can find more docs on the xPath helper here - https://wiremock.org/docs/response-templating/#xpath-helpers You can find information on the assign helper here - https://wiremock.org/docs/response-templating/#number-and-assignment-helpers

This example was build using WireMock version 3.8.0

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