Анализатор XML FANUC KAREL

#xml #parsing #karel

#xml #синтаксический анализ #karel

Вопрос:

может быть, здесь есть кто-то, кто немного знает ФАНУКА КАРЕЛА. Мне нужно создать анализатор XML, чтобы получить определенные части телеграммы.

Я начал с кода шаблона FANUC, но в настоящее время я не получаю никаких результатов. Ничего.

Здесь вы можете увидеть сообщение, я должен проанализировать:

 <?xml version="1.0" ?>
<message><name>Run.Locate.Ok</name><job>1</job><match>1</match><matches>1</matches><x>90.735872311523</x><y>-5.0591040552784</y><z>0</z><rx>0</rx><ry>0</ry><rz>166.37113177833</rz><px>90.735872311523</px><py>-5.0591040552784</py><pz>0</pz><prx>0</prx><pry>0</pry><prz>166.37113177833</prz><scale>1.0</scale><score>97.627884149551</score><time>134</time><exposure>1</exposure><identified>1</identified></message>
  

И здесь вы можете увидеть мой текущий исходный код KAREL:

 PROGRAM xmlparse
%NOLOCKGROUP
%NOPAUSESHFT
%NOPAUSE = ERROR   COMMAND   TPENABLE
%NOABORT = ERROR   COMMAND
%ENVIRONMENT xml
%include klerxmlf

CONST
    MYXML_CONST = 3

TYPE
    xmlstrct_t = STRUCTURE
        first   :   integer
        second  :   real
        third   :   boolean
        fourth  :   string[20]
    ENDSTRUCTURE

-- Local Vars
VAR
    xml_result  :   file
    status      :   INTEGER
    tag_name    :   string[32]
    attrnames   :   array[32] of string[32]
    attrvalues  :   array[32] of string[64]
    text        :   array[32] of String[128]
    xmlstrct    :   xmlstrct_t
    tag_ident   :   integer
    textdone    :   boolean
    func_code   :   integer
    text_idx    :   integer
    numattr     :   integer
    done        :   boolean 
    startdata   :   boolean
    xmlp_done   :   boolean


Routine xml_parse:boolean

BEGIN   
    -- Parse XML Data
    SET_FILE_ATR(xml_result, ATR_XML)
    CLR_IO_STAT(xml_result)
    WRITE TPDISPLAY('XML_Start',CR)
    OPEN FILE xml_result('RO','MC:result.xml')

    WRITE TPDISPLAY('File OK',CR)
    status = IO_STATUS(xml_result)
    WRITE TPDISPLAY('Status 1',CR)
    IF (status <> 0) THEN
        POST_ERR(status, '', 0, 0)
        abort
    ENDIF
    WRITE TPDISPLAY('Status 2',CR)
    xml_addtag (xml_result, 'xmlstrct_t', 32, FALSE, MYXML_CONST, status)
    WRITE TPDISPLAY('Status 3',CR)
    textdone = TRUE
    done = FALSE
    startdata = FALSE
    while (done = FALSE) DO
        xml_scan(xml_result,'message',tag_ident,func_code,status)
        WRITE TPDISPLAY('Status 4',CR)
        if (status = 0) THEN
            done = TRUE
        ENDIF
        IF (status = XML_FUNCTION) THEN
            Status = 0
            SELECT tag_ident of
                Case (MYXML_CONST) :
                    SELECT func_code of
                        Case (XML_START) :
                            text_idx = 1
                            xml_setvar (xml_result, 'message', 'xmlstrct', status)
                            xml_getdata(xml_result, numattr, attrnames, attrvalues, text[text_idx], textdone, status)
                        Case (XML_END) :
                            IF (startdata = TRUE) THEN
                                startdata = FALSE
                            ELSE
                                text_idx = 1
                                xml_setvar (xml_result, 'message', 'xmlstrct', status)
                                xml_getdata(xml_result, numattr, attrnames, attrvalues, text[text_idx], textdone, status)
                            ENDIF
                        Case (XML_TXCONT) :
                                text_idx = text_idx   1
                                xml_getdata (xml_result, numattr, attrnames, attrvalues, text[text_idx], textdone, status)
                        ELSE:
                    ENDSELECT
                ELSE:
            ENDSELECT
        ELSE
            IF (status <> XML_SCANLIM) THEN
                POST_ERR(status, '', 0, 0)
                done = TRUE
            ENDIF
        ENDIF
    ENDWHILE
    WRITE TPDISPLAY('Status 5',CR)

    xml_remtag(xml_result, 'xmlstrct_t', status)
    close file xml_result
    status = IO_STATUS(xml_result)
    IF (status <> 0) THEN
        POST_ERR(status, '', 0, 0)
        xmlp_done = FALSE
    ELSE
        xmlp_done = TRUE
    ENDIF

    WRITE TPDISPLAY('File Closed 3',CR)
    RETURN (xmlp_done)

END xml_parse

Begin
END xmlparse
  

Что мне нужно, так это отдельное содержимое тега, например, позиция.

Кто-нибудь может дать мне подсказку?

Спасибо!

Ответ №1:

В руководстве FANUC Karel определенно неясно о функциях XML. Я написал синтаксический анализатор Karel XML только один раз, 5 лет назад, поэтому я не могу быть настолько точным, насколько хотел бы, но я четко помню несколько советов, которые могут вам помочь.

Для начала попробуйте однострочный XML-файл и напишите для него специальную программу Karel, это очень поможет вам понять, как работает Karel.

Имейте в виду, что СТРУКТУРА должна точно описывать тот же тип и количество данных, которые будут содержать теги XML: структура примера, приведенного в руководстве, предназначена для XML-приложения, составленного следующим образом

 <data>
    <first>5</second>
    <second>5.5</second>
    <third>1</third>
    <fourth>some text here</forth>
</data>
  

В вашем случае позвольте мне отформатировать ваш XML:

 <message>
    <name>Run.Locate.Ok</name>
    <job>1</job>
    <match>1</match>
    <matches>1</matches>
    <x>90.735872311523</x>
    <y>-5.0591040552784</y>
    <z>0</z>
    <rx>0</rx>
    <ry>0</ry>
    <rz>166.37113177833</rz>
    <px>90.735872311523</px>
    <py>-5.0591040552784</py>
    <pz>0</pz>
    <prx>0</prx>
    <pry>0</pry>
    <prz>166.37113177833</prz>
    <scale>1.0</scale>
    <score>97.627884149551</score>
    <time>134</time>
    <exposure>1</exposure>
    <identified>1</identified>
</message>
  

Я бы предпочел более прагматичный подход:

 TYPE
    your_data = STRUCTURE
        name: STRING[64]
        job: INTEGER
        x: REAL
        -- All other things
    ENDSTRUCTURE
  

И затем используйте непосредственно функции XML без накладных расходов на циклы.

Небольшая подсказка: FANUC robots использует 32-разрядное представление с одинарной точностью для действительных чисел; если возможно, я бы предпочел использовать более короткое представление для чисел с плавающей запятой, иначе программа Karel будет сильно округлять значения, и вы можете пропустить некоторые важные данные.

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

Комментарии:

1. Спасибо за ваш ответ. Теперь я все больше и больше меняю свой код. Ваша подсказка с 32 битами, я это знаю, и это не проблема. Как бы вы написали это коротко, без цикла? Если у вас есть время, я был бы рад, если бы вы могли предоставить мне свой karel в качестве примера.

Ответ №2:

Я думаю, что проблема может быть:

 OPEN FILE xml_result('RO','MC:result.xml')
  

Должно быть:

 OPEN FILE xml_result('RW','MC:result.xml')
  

RW вместо RO при открытии XML-файла