1

在我正在工作的应用程序中,我们需要将一个巨大的 json 转换为一个更大的 XML。这两个元素的结构非常不同,因此我们决定创建一个与 XSD 匹配的 XML 文件并使用统一的表达式语言填充字段。例如:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Objects xmlns="..">
  <Object>
    <Field>${json.field}</Field>
  <Object>
<Objects>

替换${json.field}是使用JUEL完成的

运行 JUEL 过程后,我们将 xml 字符串解组到对象中,然后继续该过程。解组代码是这样的:

  private XmlObjects unmarshal(StringReader xmlString) {
    try {
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      return (XmlObjects) unmarshaller.unmarshal(xmlString);
    } catch (JAXBException e) {
      throw new RuntimeException(e);
    }
  }

我们面临的问题是json.field可以包含 XML 中不允许的字符,例如 & 或 <、>。

一个简单的解决方法是将上述方法中的所有 & 替换为 & ,但这并不能解决 < 或 > 的问题,我无法在这一点上替换它。

我想做的是在json映射到POJO时使用Jackson进行替换,但我找不到办法。到目前为止,我已经尝试创建一个自定义CharacterEscapes类并将其设置为ObjectMapper但没有用。

所以,这是总结一切的测试:

  @Test
  public void test() throws IOException {
    ObjectMapper objectMapper = Jackson.newObjectMapper();
    objectMapper.getFactory().setCharacterEscapes(new XMLCharacterEscapes());

    String json = "{\"variable\":\"a string with &\"}";
    FooJson fooJson = objectMapper.readValue(json, FooJson.class);
    assertEquals("a string with &amp;", fooJson.getVariable());
  }

这是XMLCharacterEscapes课程:

public class XMLCharacterEscapes extends CharacterEscapes {

  private final int[] asciiEscapes;

  public XMLCharacterEscapes() {
    int[] esc = CharacterEscapes.standardAsciiEscapesForJSON();
    esc['&'] = CharacterEscapes.ESCAPE_CUSTOM;
    asciiEscapes = esc;
  }

  @Override
  public int[] getEscapeCodesForAscii() {
    return asciiEscapes;
  }

  @Override
  public SerializableString getEscapeSequence(int i) {
    return new SerializedString("&amp;");
  }
}
4

2 回答 2

0

将您的字段包含在 CDATA 部分中

<Field><![CDATA[${json.field}]]></Field>

于 2018-01-30T20:20:22.180 回答
0

如果我可以建议一个替代方案,您是否可以让您的解组器在读取 XML 时将 JUEL 应用于元素值?或者,您能否在解组后遍历 XML 对象图并将 JUEL 应用于元素值?

编辑:似乎问题只是您应用替换的顺序。一旦你有了一个 XML 文档,你应该能够设置你喜欢的任何值,它会负责正确的转义。

于 2018-01-30T14:54:07.303 回答