0

I'm working in creating a simple script to generate Google site maps dynamically but i have a small issue,when i viewed the normal site maps for Google i found those lines inside the main root element which called urlset:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 

http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" 

xmlns="http://www.sitemaps.org/schemas/sitemap/0.9

I'm creating the site maps through DOMdocument PHP and i need to know how to add this header or codes to my main child ?
this is my code :

$doc = new DOMDocument('1.0', 'UTF-8');
$map = $doc->createElement('urlset');
$map = $doc->appendChild($map);
$url = $map->appendChild($doc->createElement('url'));
$url = $map->appendChild($doc->appendChild($url));
$url->appendChild($doc->createElement('loc',$link));
$url->appendChild($doc->createElement('lastmod',$date));
$url->appendChild($doc->createElement('priority',$priority));
$doc->save('sitemap.xml');

The code just work fine and generate the XML file with no problems but when i tried to check the validity of the site map by validating it, it gives this error

Element 'urlset': No matching global declaration available for the validation root OR Can not find declaration of element 'urlset'.

which caused because of the missing header i think .

John Conde
  • 217,595
  • 99
  • 455
  • 496
Dr.Neo
  • 1,240
  • 4
  • 17
  • 28

1 Answers1

1

The <urlset> element in a Google Sitemap is within the XML namespace with the URI http://www.sitemaps.org/schemas/sitemap/0.9.

So when you create that element, you need to create it within that namespace. For that you need the namespace URI and the method DOMDocument::createElementNS()Docs:

const NS_URI_SITE_MAP = 'http://www.sitemaps.org/schemas/sitemap/0.9';

$doc = new DOMDocument('1.0', 'UTF-8');

$map = $doc->createElementNS(NS_URI_SITE_MAP, 'urlset');
$map = $doc->appendChild($map);

This already creates the following XML document:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"/>

The next part is to add the XML Schema Instance Schemalocation attribute for the validation. It is an attribute in it's own namespace so again the attribute needs to be created inside a namespace and then add to the $map root element:

const NS_URI_XML_SCHEMA_INSTANCE = 'http://www.w3.org/2001/XMLSchema-instance';
const NS_PREFIX_XML_SCHEMA_INSTANCE = 'xsi';

$schemalocation = $doc->createAttributeNS(
    NS_URI_XML_SCHEMA_INSTANCE,
    NS_PREFIX_XML_SCHEMA_INSTANCE . ':schemaLocation'
);
$schemaLocation->value = sprintf('%1s %1$s.xsd', NS_URI_SITE_MAP);
$schemaLocation        = $map->appendChild($schemaLocation);

This then extends the document to (pretty printed):

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
                            http://www.sitemaps.org/schemas/sitemap/0.9.xsd"/>

As far as I know it's not possible with DOMDocument to insert line-breaks inside of the attribute value without encoding them as numeric entities. Therefore I've used a single space which is equivalent when the document is read back in.

Hope this helps.

Related:

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836