Skip to content

Commit

Permalink
Fix xml numbers decoding (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
liquetsoft authored Oct 25, 2024
1 parent 53f2d38 commit 1c4a3f8
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 37 deletions.
6 changes: 5 additions & 1 deletion src/Serializer/FiasSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ public function __construct(?array $normalizers = null, ?array $encoders = null)

if ($encoders === null) {
$encoders = [
new XmlEncoder(),
new XmlEncoder(
[
XmlEncoder::TYPE_CAST_ATTRIBUTES => false,
]
),
];
}

Expand Down
62 changes: 28 additions & 34 deletions src/XmlReader/BaseXmlReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,48 @@
/**
* Объект, который читает данные из xml файла с помощью XmlReader.
*/
class BaseXmlReader implements XmlReaderInterface
final class BaseXmlReader implements XmlReaderInterface
{
private const XML_READER_CHARSET = 'UTF-8';
private const XML_READER_PARAMS = \LIBXML_COMPACT | \LIBXML_NONET | \LIBXML_NOBLANKS;

/**
* Файл, который открыт в данный момент.
*/
protected ?\SplFileInfo $file = null;
private ?\SplFileInfo $file = null;

/**
* Xpath, по которому следует искать данные.
*/
protected string $xpath = '';
private string $xpath = '';

/**
* Объект XMLReader для чтения документа.
*/
protected ?\XMLReader $reader = null;
private ?\XMLReader $reader = null;

/**
* Текущее смещение внутри массива.
*/
protected int $position = 0;
private int $position = 0;

/**
* Флаг, который указывает, что данные были прочитаны в буфер.
*/
protected bool $isBufferFull = false;
private bool $isBufferFull = false;

/**
* Массив с буфером, для isValid и current.
*/
protected ?string $buffer = null;
private ?string $buffer = null;

/**
* {@inheritdoc}
*/
public function open(\SplFileInfo $file, string $xpath): bool
{
if (!$file->isFile() || !$file->isReadable()) {
throw new XmlException(
"File '" . $file->getPathname() . "' isn't readable or doesn't exist"
);
throw XmlException::create("File '%s' isn't readable or doesn't exist", $file->getPathname());
}

$this->file = $file;
Expand Down Expand Up @@ -132,26 +133,16 @@ public function valid(): bool
return $this->buffer !== null;
}

/**
* Деструктор.
*
* Закрывает файл, если он все еще открыт.
*/
public function __destruct()
{
$this->close();
}

/**
* Возвращает строку из файла, соответствующую элементу, или null, если разбор
* файла завершен.
*
* @throws XmlException
*/
protected function getLine(): ?string
private function getLine(): ?string
{
if (!$this->reader) {
throw new XmlException('Reader and xpath must be set before reading');
throw XmlException::create('Reader and xpath must be set before reading');
}

$return = null;
Expand All @@ -170,9 +161,9 @@ protected function getLine(): ?string
$this->reader->next();
}
} catch (\Throwable $e) {
$fileName = $this->file ? $this->file->getPathname() : '';
$message = "Error while parsing xml '{$fileName}' by '{$this->xpath}' path.";
throw new XmlException($message, 0, $e);
$fileName = $this->file?->getPathname() ?? '';
$message = "Error while parsing xml '{$fileName}' by '{$this->xpath}' path";
throw new XmlException(message: $message, previous: $e);
}

return $return;
Expand All @@ -182,7 +173,7 @@ protected function getLine(): ?string
* Пропускает все xml элементы в текущем ридере, у которых имя или вложенность
* не совпадают с указанным параметром.
*/
protected function skipUselessXml(string $nodeName, int $nodeDepth): void
private function skipUselessXml(string $nodeName, int $nodeDepth): void
{
while (
$this->reader
Expand All @@ -207,7 +198,7 @@ protected function skipUselessXml(string $nodeName, int $nodeDepth): void
*
* @throws XmlException
*/
protected function seekXmlPath(): bool
private function seekXmlPath(): bool
{
$reader = $this->resetReader();

Expand Down Expand Up @@ -238,19 +229,22 @@ protected function seekXmlPath(): bool
*
* @throws XmlException
*/
protected function resetReader(): \XMLReader
private function resetReader(): \XMLReader
{
if (!$this->file || !$this->xpath) {
throw new XmlException("File doesn't open.");
throw XmlException::create("File doesn't open");
}

$this->unsetReader();
$this->reader = new \XMLReader();

if ($this->reader->open($this->file->getPathname(), 'UTF-8', \LIBXML_COMPACT | \LIBXML_NONET | \LIBXML_NOBLANKS) === false) {
throw new XmlException(
"Can't open file '" . $this->file->getPathname() . "' for reading."
);
$res = $this->reader->open(
$this->file->getPathname(),
self::XML_READER_CHARSET,
self::XML_READER_PARAMS
);
if ($res === false) {
throw XmlException::create("Can't open file '%s' for reading", $this->file->getPathname());
}

return $this->reader;
Expand All @@ -259,7 +253,7 @@ protected function resetReader(): \XMLReader
/**
* Закрывает открытые ресурсы и сбрасывает все внутренние счетчики.
*/
protected function unsetReader(): void
private function unsetReader(): void
{
if ($this->reader) {
$this->reader->close();
Expand Down
4 changes: 2 additions & 2 deletions tests/src/Serializer/FiasSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function testDenormalize(): void
ACTSTATID="2"
NAME="Не актуальный"
TESTDATE="2019-10-10T10:10:10.02"
KOD_T_ST="10"
KOD_T_ST="227010000010000016740025000000000"
EMPTYSTRINGINT=""
/>
EOT;
Expand All @@ -41,7 +41,7 @@ public function testDenormalize(): void
$this->assertInstanceOf(FiasSerializerMock::class, $object);
$this->assertSame(2, $object->getActstatid());
$this->assertSame('Не актуальный', $object->getName());
$this->assertSame('10', $object->getKodtst());
$this->assertSame('227010000010000016740025000000000', $object->getKodtst());
$this->assertSame(0, $object->getEmptyStringInt());

$date = $object->getTestDate();
Expand Down

0 comments on commit 1c4a3f8

Please sign in to comment.