You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用WireMock虚拟化XML API时XPath提取请求值失败求助

WireMock中通过XPath提取XML请求字段生成JSON响应问题

问题背景

使用WireMock独立jar包虚拟化XML格式的API,需要将请求XML中的特定标签值通过XPath提取,填充到JSON响应中。但尝试的XPath表达式均无法正常工作,还触发了UncheckedExecutionException。

请求示例(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>

期望响应示例(JSON)

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

尝试过的XPath表达式

  • {{{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()'}}}

解决方案

核心问题是XML命名空间未正确处理:请求XML的根节点带有默认命名空间xmlns="http://www.example.com/Envelope",所有子节点都属于该命名空间,直接用标签名或简单的local-name写法会匹配失败。

方法1:绑定命名空间(推荐,可读性更高)

WireMock的XPath支持通过namespaceContext参数绑定命名空间前缀,示例如下:

{{{xpath request.body '//env:Key[env:Name="RequestNumber"]/env:Value/text()' namespaceContext='{"env": "http://www.example.com/Envelope"}'}}}

方法2:修正local-name表达式

如果不想绑定命名空间,需要确保每个节点的local-name判断覆盖完整路径,同时处理文本节点的可能空格问题(比如normalize-space()避免空白字符干扰):

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

完整WireMock映射示例

将上述XPath整合到响应模板中,完整的映射配置如下:

{
  "request": {
    "method": "POST",
    "url": "/your-api-endpoint",
    "bodyPatterns": [
      { "matchesXml": "//*[local-name()='Envelope']" }
    ]
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "body": "{
      \"event\": {
        \"source\": \"example\",
        \"type\": \"example_event\",
        \"timestamp\": \"{{{xpath request.body '//env:Timestamp/text()' namespaceContext='{\"env\": \"http://www.example.com/Envelope\"}'}}}\",
        \"payload\": {
          \"requestNumber\": \"{{{xpath request.body '//env:Key[env:Name=\"RequestNumber\"]/env:Value/text()' namespaceContext='{\"env\": \"http://www.example.com/Envelope\"}'}}}\"
        }
      }
    }",
    "transformers": ["response-template"]
  }
}

注意事项

  1. 确保WireMock启用了response-template转换器,启动命令需添加--extensions com.github.tomakehurst.wiremock.extension.responsetemplating
  2. XPath中的引号需要正确转义,在JSON映射文件中,双引号需用\"转义
  3. 使用normalize-space()处理文本节点的空白字符,避免因XML格式化空格导致匹配失败

内容的提问来源于stack exchange,提问作者ANZAR AHSAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 15:22:13