Как пропустить проверку текстов в теге xml? - PullRequest
0 голосов
/ 18 мая 2018

Я получаю XML, загруженный из bugzilla в следующем формате:

<bugzilla>
     <bug>
          <bug_id>111</bug_id>
          <short_desc>text 1 & 2</short_desc>
      </bug>
      <bug>
          <bug_id>222</bug_id>
          <short_desc>text 2 <this is a short desc> </short_desc>
     </bug>
</bugzilla>

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

  1. для & внутри первого тега (его необходимо изменить на &amp; Сообщение об ошибке: The entity name must immediately follow the '&' in the entity reference.

  2. тот же случай для <this is a short desc> текста. Ошибкасообщение The entity name must immediately follow the '&' in the entity reference.

Но я не понимаю, что оба они являются содержимым допустимых тегов. Так почему же логика проверки для такого содержимого работает? Во втором случае это не просто одинпометьте как <thisisashortdesc>, что может привести к действительной действительной ошибке, говоря, что закрывающий тег отсутствует, но в этом случае есть пробелы между.

Найдите код, использованный нижеg:

File file = new File("C: \ test \ file.xml");

    JAXBContext jaxbContext = JAXBContext.newInstance(Bugzilla.class);
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    Bugzilla bugzillaReport = (Bugzilla) jaxbUnmarshaller.unmarshal(file);

В любом случае, чтобы решить эту проблему.

1 Ответ

0 голосов
/ 18 мая 2018

Как вы знаете, действительный XML должен быть проанализирован, поскольку нет нечеткого соответствия, как в HTML.Стандартным решением является размещение <![CDATA[....]]>.( CDATA обозначает символьные данные .)

<short_desc><![CDATA[text 1 & 2]]></short_desc>
<short_desc><![CDATA[text 2 <this is a short desc> ]]></short_desc>

Это громоздко, и вопрос заключается в том, работает ли использование, когда текст вместо CDataожидается.И создание правильного XML, вероятно, проще.Apache commons также имеет StringEscapeUtils.escapeXml10(String) для этой цели.

Сначала попробуйте (CDATA).

String xml = new String(Files.readAllBytes(Paths.get("C:\\test\\file.xml")),
         StandardCharsets.UTF_8);
xml = "<?xml version=\"1.0\">\n" + xml;
xml = xml.replace("<short_desc>", "<short_desc><![CDATA[");
xml = xml.replace("</short_desc>", "]]></short_desc>");
jaxbUnmarshaller.unmarshal(new StreamSource(new StringReader(xml)));

Обратите внимание, что обратный слеш \ должен быть экранирован в строке Java..

Исправление в java 9: ​​

xml = xml.replaceAll("(?s)<short_desc>(.*)</short_desc>",
        matchResult -> "<short_desc>"
                       + StringEscapeUtils.escapeXml10(matchResult.group(1))
                       + "</short_desc>");

или без общего языка Apache StringEscapeUtils:

xml = xml.replaceAll("(?s)<short_desc>(.*)</short_desc>",
        matchResult -> "<short_desc>"
                       + matchResult.group(1)
                             .replace("&", "&amp;")
                             .replace("\"", "&quot;")
                             .replace("<", "&lt;")
                             .replace(">", "&gt;")
                       + "</short_desc>");
...