Как получить определенные элементы из файла, структура которого похожа на XML в Java - PullRequest
1 голос
/ 06 ноября 2019

У меня есть .sic-файл, структура которого похожа на XML, но не полностью. Там у меня есть раздел Channel2, где я хочу прочитать некоторые элементы. Раздел выглядит так:

.
.
.
<SI name = "Channel2" type = "list">
           <SI name = "SecsPortConfig" type = "list">
              <SI name = "PortType" type = "string">'XXX'</SI>
              <SI name = "Protocol" type = "string">'XXX'</SI>
              <SI name = "Serial" type = "list">
                 <SI name = "Port" type = "int">'XXX'</SI>
                 <SI name = "Speed" type = "int">'XXXX'</SI>
              </SI>
              <SI name = "Socket" type = "list">
                 <SI name = "ConnectionMode" type = "string">'XXX'</SI>
                 <SI name = "LocalHost" type = "string">'XXX.XXX.XXX.XXX'</SI>
                 <SI name = "LocalPort" type = "int">'XXX'</SI>
                 <SI name = "RemoteHost" type = "string">'XXX.XXX.XXX'</SI>
                 <SI name = "RemotePort" type = "int">'XXX'</SI>
              </SI>
              <SI name = "HSMS" type = "list">
                 <SI name = "T5" type = "int">'XXX'</SI>
                 <SI name = "T6" type = "int">'XXX'</SI>
                 <SI name = "T7" type = "int">'XXX'</SI>
                 <SI name = "T8" type = "int">'XXX'</SI>
                 <SI name = "LinkTestTime" type = "int">'XXX'</SI>
              </SI>
              <SI name = "SECSI" type = "list">
                 <SI name = "T1" type = "int">'XXX'</SI>
                 <SI name = "T2" type = "int">'XXX'</SI>
                 <SI name = "T4" type = "int">'XXX'</SI>
                 <SI name = "RTY" type = "int">'XXX'</SI>
                 <SI name = "IsHost" type = "bool">'XXX'</SI>
                 <SI name = "IsMaster" type = "bool">'XXX'</SI>
                 <SI name = "InterleaveBlocks" type = "bool">'XXX'</SI>
              </SI>
              <SI name = "SECSII" type = "list">
                 <SI name = "DeviceID" type = "int">'XXX'</SI>
                 <SI name = "T3" type = "int">'XXX'</SI>
                 <SI name = "MultipleOpen" type = "bool">'XXX'</SI>
                 <SI name = "AutoDeviceID" type = "bool">'XXX'</SI>
              </SI>
              <SI name = "Log" type = "list">
                 <SI name = "LogCharError" type = "bool">'XXX'</SI>
                 <SI name = "LogCharEvent" type = "bool">'XXX'</SI>
                 <SI name = "LogCharReceive" type = "bool">'XXX'</SI>
                 <SI name = "LogCharSend" type = "bool">'XXX'</SI>
                 <SI name = "LogSecsIHsmsError" type = "bool">'XXX'</SI>
                 <SI name = "LogSecsIHsmsEvent" type = "bool">'XXX'</SI>
                 <SI name = "LogSecsIHsmsReceive" type = "bool">'XXX'</SI>
                 <SI name = "LogSecsIHsmsSend" type = "bool">'XXX'</SI>
                 <SI name = "LogSecsIIError" type = "bool">'XXX'</SI>
                 <SI name = "LogSecsIIEvent" type = "bool">'XXX'</SI>
                 <SI name = "LogSecsIIReceive" type = "bool">'XXX'</SI>
                 <SI name = "LogSecsIISend" type = "bool">'XXX'</SI>
              </SI>
           </SI>
           <SI name = "UseSeparateSECSLogFile" type = "bool">'XXX'</SI>
           <SI name = "Connected" type = "bool">'XXX'</SI>
           <SI name = "MessageFilters" type = "list">
              <SI name = "DeviceIDList" type = "list"/>
              <SI name = "StreamFunctionList" type = "list"/>
           </SI>
           <SI name = "SafeMessageFilters" type = "list">
              <SI name = "DeviceIDList" type = "list"/>
              <SI name = "StreamFunctionList" type = "list"/>
           </SI>
        </SI>
        .
        .
        .

Если бы это был xml-файл, я мог бы его проанализировать и прочитать элементы, но как мне это сделать с этим типом файла? Я хочу извлечь элементы RemoteHost и RemotePort. Я попробовал это сейчас с BufferedReader, и я получаю Раздел Channel2 из файла со вставкой этого раздела в строку, но как мне извлечь конкретные значения элементов, которые я хочу? Я мог бы сделать это с помощью подстроки и некоторых других String-методов, но нет ли более простого способа сделать это? Это мой код:

    File file = new File("C:\\Users\\but\\Desktop\\ExternalswPassThroughSrv.sic");

    int counter = 0;

    BufferedReader br = new BufferedReader(new FileReader(file));

    String cl;
    String finalString = "";
    while ((cl = br.readLine()) != null) {
        if (cl.contains("Channel2")) {
            counter = 63;
        }
        if(counter != 0){
            //System.out.println(cl);
            finalString += cl + "\n";
            counter--;
        }
    }
    System.out.println(finalString);

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

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

После этого вы можете проанализировать его в документе и использовать XPath для извлечения требуемой информации.

Вот несколько примеров кода Java, который может работать для вас (Я не включил xml, для ясности)

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.StringReader;

public class ConvertXml {
    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException, TransformerException, XPathExpressionException {
        // Your XML-like content
        String xmlString = "xml here";

        // transform xml-Fragment into well-formed xml with root element
        String xmlStringWellformed = "<content>" + xmlString + "</content>";

        // parse well-formed xml
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(new InputSource(new StringReader(xmlStringWellformed)));

        // build xpath expression
        String xPathRemoteHost = "//SI[@name='Channel2']/SI[@name='SecsPortConfig']/SI[@name='Socket']/SI[@name='RemoteHost']/text()";
        String xPathRemotePort = "//SI[@name='Channel2']/SI[@name='SecsPortConfig']/SI[@name='Socket']/SI[@name='RemotePort']/text()";
        XPath xPath = XPathFactory.newInstance().newXPath();

        // Use XPath for extraction
        String remoteHost = (String) xPath.compile(xPathRemoteHost).evaluate(document, XPathConstants.STRING);
        String remotePort = (String) xPath.compile(xPathRemotePort).evaluate(document, XPathConstants.STRING);

        System.out.println("RemoteHost: " + remoteHost);
        System.out.println("RemotePort: " + remotePort);
    }
}

Источники: Baeldung - Введение в XPath с Java

1 голос
/ 06 ноября 2019
Document _myDoc = null;

LSInput input  = implLS.createLSInput();

input.setStringData(requestXML);

_myDoc = parser.parse(input);

SI = ((NodeList)_myDoc.getElementsByTagName("MessageFilters")).item(0).getFirstChild().getNodeValue();

вы можете получить значения узла элемента XML с помощью getElementsByTagName. Но для этого вам нужно иметь разные имена элементов. Это не ответ. Это не ответ. Просто подсказка. Попробуйте это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...