Skip to content

Releases: veewee/xml

Version 3.1.0

29 Jan 18:18
3.1.0
7cb255b
Compare
Choose a tag to compare

What's Changed

  • Fix psalm 5.20 by @veewee in #69
  • Attempt to create file and directory when starting a writer for a file by @veewee in #71

Full Changelog: 3.0.0...3.1.0

Version 3.0.0

14 Jan 13:07
3.0.0
90affd5
Compare
Choose a tag to compare

What's Changed

  • Add reader MatchingNode results and a signal to stop reading by @veewee in #66
  • Drop deprecations by @veewee in #68

Breaking changes

This new version introduces 1 breaking change in the Reader component:

Reader

Instead of providing the results as a string, this string are now wrapped with a MatchingNode.
This allows us to also provide information like the matched NodeSequence and some shortcut functions for converting this XML into a DOM Document or decoded version of the XML.

If you are using the Reader of v2, you will have to change your implementation to support the MatchingNode instead of the string result from previous version.

An example:

use VeeWee\Xml\Dom\Configurator;
use VeeWee\Xml\Reader\Signal;
use function VeeWee\Xml\Reader\Matcher\element_name;
use function VeeWee\Xml\Reader\Matcher\sequence;


$xml = <<<XML
    <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
      <services>
        <service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
        <service id="kernel" class="TicketSwap\Kernel" public="true" synthetic="true" autoconfigure="true">
          <tag xmlns="http://symfony.com/schema/dic/tag-1" name="controller.service_arguments">1</tag>
          <tag xmlns="http://symfony.com/schema/dic/tag-2"  name="routing.route_loader">2</tag>
        </service>
      </services>
    </container>
XML;


$reader = VeeWee\Xml\Reader\Reader::fromXmlString($xml);
$signal = new Signal();

foreach ($reader->provide(element_name('tag'), $signal) as $tag) {
    // New result of the reader is now a DTO that contains both the XML and node sequence.
    var_dump(
       // This is the previous matched XML `string`
        $tag->xml(),
        // Contains a match function so that you can run a secondary matcher on the result.
        // Can be handy if you are matching on multiple paths in one read for example.
        $tag->matches(sequence(
                element_name('container'),
                element_name('services'),
                element_name('service'),
                element_name('tag')
        )),
        // You can now directly pull the xml into a DOM Document with or without a DOM configurator.
        $tag->intoDocument(Configurator\canonicalize()),
        // Or decode it directly using xml_decode:
        $tag->decode(Configurator\canonicalize()),
        // You can get access to the current matching NodeSequence data:
        $tag->nodeSequence(),
    );

    // Stops reading on first `tag` match.
    $signal->stop();
}

Removed deprecations:

Following functions were deprecated in v2 and are removed from v3:

  • Reader\Matcher\node_name: Use Reader\Matcher\element_name instead.
  • Reader\Matcher\node_attribute: Use Reader\Matcher\attribute_value instead.

Full Changelog: 2.14.0...3.0.0

Version 2.14.0

14 Jan 12:27
2.14.0
143c565
Compare
Choose a tag to compare

What's Changed

  • Add stringify and document element shortcuts to XML Document by @veewee in #67

Some functions I happen a lot are causing some verbosity. By adding them to the Document class, it makes it faster to do trivial stuff like e.g. Grabbing the document element or stringifying a part of the document.

document_element locator:

use VeeWee\Xml\Dom\Document;
use function VeeWee\Xml\Dom\Locator\document_element;

$doc = Document::fromXmlFile('some.xml');
$rootElement = $doc->locate(document_element());

// Since this is a common action, there is also a shortcut:
$doc->locateDocumentElement();

Stringify

use VeeWee\Xml\Dom\Document;

$doc = Document::fromXmlFile('some.xml');

// Get full XML including the XML declaration tag:
$xml = $doc->toXmlString();

// OR, get only the XML part without declaration:
$xml = $doc->stringifyDocumentElement();

// Or stringify a specific DOM node:
$xml = $doc->stringifyNode($someNode);

Full Changelog: 2.13.0...2.14.0

Version 2.13.0

01 Dec 13:46
2.13.0
3172e96
Compare
Choose a tag to compare

What's Changed

Full Changelog: 2.12.0...2.13.0

Version 2.12.0

23 Nov 13:33
2.12.0
78a4ba4
Compare
Choose a tag to compare

What's Changed

Full Changelog: 2.11.2...2.12.0

Version 2.11.2

12 Nov 18:08
2.11.2
e84f554
Compare
Choose a tag to compare

What's Changed

  • Revert "More stable node loading" by @veewee in #64

This commit reverts The more stable node loading from #61.
It turns out that this solution introduces some more problems.

It seems like a better idea to wait for a fix in PHP than to deal with these newer issues in this package.

Full Changelog: 2.11.1...2.11.2

Version 2.11.1

09 Nov 07:24
2.11.1
2331ce1
Compare
Choose a tag to compare

What's Changed

Full Changelog: 2.11.0...2.11.1

Version 2.11.0

05 Nov 14:34
2.11.0
c1978d9
Compare
Choose a tag to compare

What's Changed

  • Explain how the reader component works by @veewee in #59
  • Make namespace remover configurable by @veewee in #60

Full Changelog: 2.10.0...2.11.0

Version 2.10.0

03 Nov 07:07
2.10.0
43c8e0e
Compare
Choose a tag to compare

What's Changed

Full Changelog: 2.9.0...2.10.0

Version 2.9.0

01 Nov 18:16
2.9.0
8dda371
Compare
Choose a tag to compare

What's Changed

  • Introduce the nested() XML Reader matcher by @veewee in #56

Provide nested matchers that represents parts of an XML tree.
It can be used similar to the //user xpath operator to search on any matching node at any level in the XML

Given:

<root>
    <users>
        <user locale="nl">Jos</user>
        <user>Bos</user>
        <user>Mos</user>    
    </users>
</root>

This matcher will grab the user element with locale="nl"

use \VeeWee\Xml\Reader\Matcher;

Matcher\nested(
    // Breakpoint 1: <root />
    Matcher\document_element(),
    // Breakpoint 2: <user locale="nl">Jos</user>
    // Searches for all elements that matches `<user />` and attribute `locale="nl"` in the `<root />` document.
    // Note that you can skip matching on `<users />` here : it's not an exact matcher
    Matcher\all( 
        Matcher\element_name('user'),
        Matcher\attribute_value('locale', 'nl')
    )
);

Every provided matcher acts as a breakpoint in the NodeSequence for the next matcher,
making it composable with the exact XML tree sequence matcher as well.

use \VeeWee\Xml\Reader\Matcher;

Matcher\nested(
    // Breakpoint 1: <root />
    Matcher\document_element(),
    // Breakpoint 2: <user />
    // The nested matcher will provide the NodeSequence starting from the element after previous match.
    // The sequence will basically receive: 'users > user'
    Matcher\sequence( 
        // Level 0: The element inside <root /> at level 0 must exactly match <users /> 
        Matcher\element_name('users'),
        // Level 1: The element inside <root /> at level 1 must exactly match <user />
        Matcher\element_name('user'),
    ),
    // Breakpoint 3: <email />
    // After matching a sequence, you can still continue matching deeper or adding even more sequences:
    Matcher\element_name('email')
);

Full Changelog: 2.8.0...2.9.0