QuickFixJ создать сообщение из строки XML - PullRequest
0 голосов
/ 08 июня 2018

QuickFixJ Класс сообщения имеет метод toXML (), который преобразует сообщение в строку XML.Есть ли способ, как я могу создать объект сообщения из строки XML?Мне нужна обратная функция toXML (), т.е. я хочу создать сообщение из xml.

1 Ответ

0 голосов
/ 31 июля 2018

Нет ничего подобного встроенному. На самом деле в этом нет необходимости, поскольку обычно для этого не было бы сценария использования.

Я написал класс, который это делает.Порядок тегов может отличаться от входного сообщения (но спецификация FIX не дает никаких гарантий относительно порядка тегов, кроме как внутри групп), поскольку экспортер XML сортирует по номеру тега, и поэтому первоначальный порядок тегов теряется.

Он работает только с одним сообщением в файле XML, но его можно легко адаптировать для работы с несколькими сообщениями.

Для создания * 1010 можно использовать стандарт MessageUtils.parse.* из результирующей строки.

Дайте мне знать, если у вас возникнут проблемы.

class XmlMessage
{
    private final String xml;
    private final String delimiter;

    XmlMessage(final String xml, final String delimiter)
    {
        this.xml = xml;
        this.delimiter = delimiter;
    }

    public String toFixMessage() throws IOException, SAXException, ParserConfigurationException
    {
        final Document doc = DocumentBuilderFactory.newInstance()
            .newDocumentBuilder()
            .parse(new ByteArrayInputStream(xml.getBytes()));

        final StringBuilder messageBuilder = new StringBuilder();
        build(messageBuilder, doc, "header");
        build(messageBuilder, doc, "body");
        build(messageBuilder, doc, "trailer");
        return messageBuilder.toString();
    }

    private void build(final StringBuilder messageBuilder, final Document doc, final String section)
    {
        final NodeList sectionRoot = doc.getElementsByTagName(section);
        final NodeList sectionChildren = sectionRoot.item(0).getChildNodes();
        build(messageBuilder, sectionChildren);
    }

    private void build(final StringBuilder messageBuilder, final NodeList nodeList)
    {
        final Set<String> numInGroupTags = getNumInGroupTags(nodeList);
        for (int i = 0; i < nodeList.getLength(); i++)
        {
            final Node node = nodeList.item(i);
            if (node.getNodeName().equals("field") && !numInGroupTags.contains(getTagNumber(node)))
            {
                messageBuilder.append(getTagNumber(node))
                    .append('=')
                    .append(node.getTextContent())
                    .append(delimiter);
            }
            else if (node.getNodeName().equals("groups"))
            {
                final NodeList groupElems = node.getChildNodes();
                messageBuilder.append(getTagNumber(node))
                    .append('=')
                    .append(getGroupCount(groupElems))
                    .append(delimiter);
                for (int j = 0; j < groupElems.getLength(); j++)
                {
                    build(messageBuilder, groupElems.item(j).getChildNodes());
                }
            }
        }
    }

    private Set<String> getNumInGroupTags(final NodeList nodeList)
    {
        final Set<String> numInGroupTags = new HashSet<>();
        for (int i = 0; i < nodeList.getLength(); i++)
        {
            if (nodeList.item(i).getNodeName().equals("groups"))
            {
                numInGroupTags.add(getTagNumber(nodeList.item(i)));
            }
        }
        return numInGroupTags;
    }

    private String getTagNumber(final Node node)
    {
        return node.getAttributes().getNamedItem("tag").getTextContent();
    }

    private int getGroupCount(final NodeList groupRoot)
    {
        int count = 0;
        for (int j = 0; j < groupRoot.getLength(); j++)
        {
            if (groupRoot.item(j).getNodeName().equals("group")) count++;
        }
        return count;
    }
}
...