X500::DN::Marpa::DN - Backcompat module to emulate the DN part of X500::DN


This is scripts/

        #!/usr/bin/env perl

        use strict;
        use warnings;

        use X500::DN::Marpa::DN;
        use X500::DN::Marpa::RDN;

        # -----------------------

        print "Part 1:\n";

        my($dn)   = X500::DN::Marpa::DN -> new;
        my($text) = 'foo=FOO + bar=BAR + frob=FROB, baz=BAZ';

        $dn -> ParseRFC2253($text);

        print "Parsing:     $text\n";
        print 'RDN count:   ', $dn -> getRDNs, " (Expected: 2)\n";
        print 'DN:          ', $dn -> getRFC2253String, " (Expected: baz=BAZ,foo=FOO+bar=BAR+frob=FROB)\n";
        print 'X500 string: ', $dn -> getX500String, " (Expected: {foo=FOO+bar=BAR+frob=FROB+baz=BAZ})\n";
        print '-' x 50, "\n";
        print "Part 2:\n";

        my($rdn)       = $dn -> getRDN(0);
        my $type_count = $rdn -> getAttributeTypes;
        my(@types)     = $rdn -> getAttributeTypes;

        print 'RDN(0):      ', $rdn -> dn, "\n";
        print "Type count:  $type_count (Expected: 3)\n";
        print "Type [0]:    $types[0] (Expected: foo)\n";
        print "Type [1]:    $types[1] (Expected: bar)\n";

        my(@values) = $rdn -> getAttributeValue('foo');

        print "Value [0]:   $values[0] (Expected: FOO+bar=BAR+frob=FROB)\n";

        my($has_multi) = $dn -> hasMultivaluedRDNs;

        print "hasMulti:    $has_multi (Expected: 1)\n";
        print '-' x 50, "\n";
        print "Part 2:\n";

        $rdn = $dn -> getRDN(1);

        @values = $rdn -> getAttributeValue('baz');

        print 'RDN(1):      ', $rdn -> dn, "\n";
        print "Value [0]:   $values[0] (Expected: BAZ)\n";
        print '-' x 50, "\n";

Output of scripts/

        Part 1:
        Parsing:     foo=FOO + bar=BAR + frob=FROB, baz=BAZ
        RDN count:   2 (Expected: 2)
        DN:          baz=BAZ,foo=FOO+bar=BAR+frob=FROB (Expected: baz=BAZ,foo=FOO+bar=BAR+frob=FROB)
        X500 string: {foo=FOO+bar=BAR+frob=FROB+baz=BAZ} (Expected: {foo=FOO+bar=BAR+frob=FROB+baz=BAZ})
        Part 2:
        RDN(0):      foo=FOO+bar=BAR+frob=FROB
        Type count:  3 (Expected: 3)
        Type [0]:    foo (Expected: foo)
        Type [1]:    bar (Expected: bar)
        Value [0]:   FOO+bar=BAR+frob=FROB (Expected: FOO+bar=BAR+frob=FROB)
        hasMulti:    1 (Expected: 1)
        Part 2:
        RDN(1):      baz=BAZ
        Value [0]:   BAZ (Expected: BAZ)


X500::DN::Marpa::DN provides a Marpa::R2-based parser for parsing X.500 Distinguished Names.

This module emulates the DN parts of X500::DN.


o X500::DN

This module was based on the obsolete RFC2253: Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names.

o X500::DN::Marpa and X500::DN::Marpa::DN

These modules are based on RFC4514: Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names.

See also X500::DN::Marpa and X500::DN::Marpa::RDN.


This module is available as a Unix-style distro (*.tgz).

See for help on unpacking and installing distros.


Install X500::DN::Marpa as you would any Perl module:


        cpanm X500::DN::Marpa

or run:

        sudo cpan X500::DN::Marpa

or unpack the distro, and then either:

        perl Build.PL
        ./Build test
        sudo ./Build install


        perl Makefile.PL
        make (or dmake or nmake)
        make test
        make install

Constructor and Initialization

new() is called as my($parser) = X500::DN::Marpa::DN -> new(k1 => v1, k2 => v2, ...).

It returns a new object of type X500::DN::Marpa::DN.

Key-value pairs accepted in the parameter list (see corresponding methods for details:

o (None)


This module is a subclass of X500::DN::Marpa and shares all its options to new(), and all its methods. See "Constructor and Initialization" in X500::DN::Marpa and "Methods" in X500::DN::Marpa.

Further, it has these methods:


Returns the DN as a string.

And yes, it's really based on RFC4514, as it says in the "Description".

The DN is what was passed to "ParseRFC2253($dn)".


Returns an object of type X500::DN::Marpa::RDN, containing the $n-th RDN, or returns '' if $n is out of range.

$n counts from 0.

The returned object has already parsed the RDN, so you use that object via the methods documented in X500::DN::Marpa::RDN.

If the input is ',DC=example,DC=com', rdn(0) returns an object which has parsed ''. Note the lower-case 'uid'.

Warning: The parent class X500::DN::Marpa counts RDNs from 1.


Returns the number of RDNs in the DN parsed.


Returns what X500::DN calls an X500 version of the DN.


Returns a Boolean, 0 meaning there are no multvalued RDNs, and 1 meaning there is at least 1 such RDN.


See "Constructor and Initialization" for details on the parameters accepted by "new()".


Parses $dn and returns $self (sic).

This has to be the first method (after "new()" of course) which you call on an object of type X500::DN::Marpa::DN.

So, you are expected to do this:

        my($parser) = X500::DN::Marpa::DN -> new;

        $parser -> ParseRFC2253($a_dn);

And to just ignore the return value. After this, you call methods on $parser.

If you do this:

        my($parser) = X500::DN::Marpa::DN -> new;
        my($dn)     = $parse -> ParseRFC2253($a_dn);

It will work of course, but you have 2 copies of $parser, and you (probably) call methods on $dn.

So, you could do this:

        my($dn) = X500::DN::Marpa::DN -> new -> ParseRFC2253($a_dn);

And just ignore the intermediary copy, which has been discarded. After this, you call methods on $dn.

This means that to patch old code, just convert:

        my($dn) = X500::DN -> ParseRFC2253


        my($dn) = X500::DN::Marpa::DN -> new -> ParseRFC2253


See "FAQ" in X500::DN::Marpa.

How to I transition to X500::DN::Marpa::DN before switching to X500::DN::Marpa?

See scripts/

How do I upgrade code from X500::DN to X500::DN::Marpa?

See scripts/

You can think of scripts/ as scripts/!

How do you handle attribute values in double-quotes?

RFC4514 does not discuss this topic.

So, I ignore the quotes, because I assume none of your other software accepts them anyway, since you're not using them any more, right?


See "References" in X500::DN::Marpa.

See Also


Machine-Readable Change Log

The file Changes was converted into Changelog.ini by Module::Metadata::Changes.

Version Numbers

Version numbers < 1.00 represent development versions. From 1.00 up, they are production versions.



Email the author, or log a bug on RT:


X500::DN::Marpa was written by Ron Savage <> in 2015.

Marpa's homepage:

My homepage:


Australian copyright (c) 2015, Ron Savage.

        All Programs of mine are 'OSI Certified Open Source Software';
        you can redistribute them and/or modify them under the terms of
        The Artistic License 2.0, a copy of which is available at: