esc_xml

The timeline below displays how wordpress function esc_xml has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.1

/**
 * Escaping for XML blocks.
 *
 * @since 5.5.0
 *
 * @param string $text Text to escape.
 * @return string Escaped text.
 */
function esc_xml($text)
{
    $safe_text = wp_check_invalid_utf8($text);
    $cdata_regex = '\<\!\[CDATA\[.*?\]\]\>';
    $regex = <<<EOF
    /
    \t(?=.*?{$cdata_regex})                 # lookahead that will match anything followed by a CDATA Section
    \t(?<non_cdata_followed_by_cdata>(.*?)) # the "anything" matched by the lookahead
    \t(?<cdata>({$cdata_regex}))            # the CDATA Section matched by the lookahead
    
    |\t                                      # alternative
    
    \t(?<non_cdata>(.*))                    # non-CDATA Section
    /sx
    EOF;
    $safe_text = (string) preg_replace_callback($regex, static function ($matches) {
        if (!isset($matches[0])) {
            return '';
        }
        if (isset($matches['non_cdata'])) {
            // escape HTML entities in the non-CDATA Section.
            return _wp_specialchars($matches['non_cdata'], ENT_XML1);
        }
        // Return the CDATA Section unchanged, escape HTML entities in the rest.
        return _wp_specialchars($matches['non_cdata_followed_by_cdata'], ENT_XML1) . $matches['cdata'];
    }, $safe_text);
    /**
     * Filters a string cleaned and escaped for output in XML.
     *
     * Text passed to esc_xml() is stripped of invalid or special characters
     * before output. HTML named character references are converted to their
     * equivalent code points.
     *
     * @since 5.5.0
     *
     * @param string $safe_text The text after it has been escaped.
     * @param string $text      The text prior to being escaped.
     */
    return apply_filters('esc_xml', $safe_text, $text);
}

WordPress Version: 5.5

/**
 * Escaping for XML blocks.
 *
 * @since 5.5.0
 *
 * @param string $text Text to escape.
 * @return string Escaped text.
 */
function esc_xml($text)
{
    $safe_text = wp_check_invalid_utf8($text);
    $cdata_regex = '\<\!\[CDATA\[.*?\]\]\>';
    $regex = <<<EOF
    /
    \t(?=.*?{$cdata_regex})                 # lookahead that will match anything followed by a CDATA Section
    \t(?<non_cdata_followed_by_cdata>(.*?)) # the "anything" matched by the lookahead
    \t(?<cdata>({$cdata_regex}))            # the CDATA Section matched by the lookahead
    
    |\t                                      # alternative
    
    \t(?<non_cdata>(.*))                    # non-CDATA Section
    /sx
    EOF;
    $safe_text = (string) preg_replace_callback($regex, static function ($matches) {
        if (!$matches[0]) {
            return '';
        }
        if (!empty($matches['non_cdata'])) {
            // escape HTML entities in the non-CDATA Section.
            return _wp_specialchars($matches['non_cdata'], ENT_XML1);
        }
        // Return the CDATA Section unchanged, escape HTML entities in the rest.
        return _wp_specialchars($matches['non_cdata_followed_by_cdata'], ENT_XML1) . $matches['cdata'];
    }, $safe_text);
    /**
     * Filters a string cleaned and escaped for output in XML.
     *
     * Text passed to esc_xml() is stripped of invalid or special characters
     * before output. HTML named character references are converted to their
     * equivalent code points.
     *
     * @since 5.5.0
     *
     * @param string $safe_text The text after it has been escaped.
     * @param string $text      The text prior to being escaped.
     */
    return apply_filters('esc_xml', $safe_text, $text);
}