@Override
    public String getXmpXml(final ByteSource byteSource, final XmpImagingParameters params) throws ImagingException, IOException {

        final PsdImageContents imageContents = readImageContents(byteSource);

        final PsdHeaderInfo header = imageContents.header;
        if (header == null) {
            throw new ImagingException("PSD: Couldn't read Header");
        }

        final List<ImageResourceBlock> blocks = readImageResourceBlocks(byteSource, new int[] { IMAGE_RESOURCE_ID_XMP, }, -1);

        if (blocks.isEmpty()) {
            return null;
        }

        final List<ImageResourceBlock> xmpBlocks = new ArrayList<>(blocks);
        if (xmpBlocks.isEmpty()) {
            return null;
        }
        if (xmpBlocks.size() > 1) {
            throw new ImagingException("PSD contains more than one XMP block.");
        }

        final ImageResourceBlock block = xmpBlocks.get(0);

        // segment data is UTF-8 encoded xml.
        return new String(block.data, 0, block.data.length, StandardCharsets.UTF_8);
    }
Extracts embedded XML metadata as XML string.

@param byteSource File containing image data.
@param params     Map of optional parameters, defined in ImagingConstants.
@return Xmp Xml as String, if present. Otherwise, returns null.
src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java