2016-04-22 4 views
1

Я использую Camel и пытаюсь установить некоторые заголовки на основе XML-файла. Проблема в том, что мне нужно установить 2 заголовка, которые объединены в один атрибут в xml и разделены двоеточием ':'.Получение подстроки индексом символа в xpath для Camel

Вот XML-строка:

<Alarm AlarmID="CC4567:180" DeviceID="CC0000:10.254.0.146" TimeStamp="2016-01-31 18:51:29.488"> 

Мне нужно выделить две части AlarmId. Я знаю, что могу использовать следующее:

<camel:setHeader headerName="firstPart"> 
    <xpath resultType="java.lang.String">substring(/ticket/alarmId,1,6)</xpath> 
</camel:setHeader> 

Но проблема в том, что первая часть фактически не ограничена 6 символами. Я попытался следующие, но я получаю сообщение об ошибке:

substring(/ticket/alarmId, 1, indexOf(':')-1) 

ошибка:
camel.builder.xml.InvalidXPathExpression: Invalid XPath: подстрока (/ билет/AlarmId, IndexOf (':')). Причина: javax.xml.xpath.XPathExpressionException: net.sf.saxon.trans.XPathException: Неизвестная системная функция indexOf()

Так что мой вопрос в том, есть ли другой способ сделать это, поскольку кажется, что верблюд не поддерживает indexOf(). Цель состоит в том, чтобы у меня было 2 заголовка, firstPart = CC4567 и secondPart = 180

ответ

1

Похоже, вы используете саксон, а не поддерживает , он не содержит функции indexOf. Вам нужно использовать действительную функцию xPath, чтобы получить то, что вы хотите сделать. Попробуйте использовать функцию tokenize() в xPath 2.0, которая должна позволить вам разбить строку на «:».

+0

Правильно я использую саксонский, так что я буду смотреть в токенизировать(). Любой шанс, это простая вещь, которую вы могли бы привести для моего случая? –

+1

Проверьте тестовые примеры tokenize на странице https://github.com/apache/camel/blob/master/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathTest.java. Кстати, если это было полезно, подумайте над тем, чтобы ответить на мой ответ или комментарии. Было бы полезно! –

+0

Ваша фраза предполагает, что существует определенная функция indexOf, а саксон как-то не в состоянии ее не поддерживать. На самом деле такой функции нет. Если бы была такая функция, и если бы она выполняла нечто похожее на функции Java и Javascript с тем же именем, для этого потребовались бы два аргумента. –

0

Кажется IndexOf не определенная функция, но подстрока-ранее() и substring-after() являются, которые работают отлично для моей ситуации:

<camel:setHeader headerName="firstPart"> 
    <xpath resultType="java.lang.String">substring-before(/ticket/alarmId, ':')</xpath> 
</camel:setHeader> 
<camel:setHeader headerName="secondPart"> 
    <xpath resultType="java.lang.String">substring-after(/ticket/alarmId, ':')</xpath> 
</camel:setHeader> 

Это также возможно с Tokenizer, как это было предложено в другой ответ, используя что будет выглядеть следующим образом:

<camel:setHeader headerName="firstPart"> 
    <xpath resultType="java.lang.String">tokenize(/ticket/alarmId,':')[1]</xpath> 
</camel:setHeader> 
<camel:setHeader headerName="secondPart"> 
    <xpath resultType="java.lang.String">tokenize(/ticket/alarmId,':')[2]</xpath> 
</camel:setHeader> 

Я пошел с первым вариантом, как я думаю, что он имеет лучшую читаемость

+2

Вы также можете использовать 'substring-before (/ ticket/alarmId, ':')' и 'substring-after (/ ticket/alarmId, ':')' –

+0

Спасибо @MichaelKay, это намного красивее читаемо, обновит мой ответ с этим –