SlideShare uma empresa Scribd logo
1 de 4
Livro: Pro PHP XML and Web Services
Apresentando o XML Canonical
A especificação XML da Canonical (http://www.w3.org/TR/xml-c14n) estabelece um método
para determinar se dois documentos são idênticos. O problema subjacente é que podem ser criados
documentos que signifiquem a mesma coisa e que tenham o mesmo conteúdo com
diferentes representações físicas. Isso dificulta determinar se os dois documentos são realmente
idênticos. Com o XML canônico, dois documentos com o mesmo forma canônica
são consideradas idênticas, mesmo que suas representações físicas não sejam idênticas.
Antes de prosseguir, você deve entender qual é a forma canônica. A especificação
define forma canônica de um documento para a representação física do documento
criado usando os seguintes métodos:
• O documento está codificado em UTF-8.
• Quebras de linha normalizam para #xA na entrada, antes da análise.
• Valores de atributos são normalizados, como se fosse um processador de validação.
• As referências de entidades analisadas e de caractere são substituídas.
• As seções CDATA são substituídas pelo conteúdo de seus caracteres.
• A declaração XML e a DTD são removidas.
• Elementos vazios são convertidos em pares de tag de início e fim.
• O espaço em branco fora do elemento do documento e dentro das tags de início e fim é
normalizado.
• Todo espaço em branco no conteúdo do personagem é retido (excluindo caracteres removidos
durante
normalização de alimentação de linha).
• Os delimitadores de valores de atributos são definidos entre aspas (aspas duplas).
• Caracteres especiais em valores de atributos e conteúdo de caracteres são substituídos por
caracteres
referências.
Declarações de espaço de nomes supérfluas são removidas de cada elemento.
• Os atributos padrão são adicionados a cada elemento.
• A ordem lexicográfica é imposta às declarações e atributos do namespace de cada
elemento.
Se você olhar através desta lista, você verá alguns itens que tornam as coisas difíceis quando
usando PHP para criar XML canônico. Você pode resolver muitos desses problemas usando o
analisador opções ao carregar um documento. Usando LIBXML_NOENT, LIBXML_DTDLOAD,
LIBXML_DTDATTR, e LIBXML_NOCDATA em combinação irá substituir referências de
entidades com seu conteúdo, carregar DTD para garantir que os IDs sejam manipulados, padronize
todos os atributos para que eles sejam fisicamente árvore e converta todos os CDATA em conteúdo
de texto. Isso deixa alguns itens que não são executados automaticamente.
Você poderia manipular o DTD de duas maneiras. Crie um novo documento e faça
uma cópia profunda ou importe o elemento do documento para o novo documento. Em seguida,
imprima o documento usando o elemento do documento como o contexto ou use XSL. Você
também pode lidar com
Declaração XML de duas maneiras. Usando o DOM, você pode imprimir o documento usando o
elemento documento como o contexto. Ou, usando XSL, supondo que você usou o analisador já
mencionado opções, você pode executar uma transformação no documento onde a folha de estilo
retorna elemento do documento para a árvore de resultados e omite a declaração XML se estiver
sendo serializado. Para exemplo:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
Se isso for usado para retornar um objeto DOMDocument, a declaração DTD e XML terá sido
removido ao serializar usando o elemento document como contexto ao serializar:
$root = $doc->documentElement;
print $doc->saveXML($root);
Nota: A serialização de um documento usando a API do DOM para remover a declaração DTD e
XML pode ser feito somente ao serializar para uma string. Serializar para um arquivo não suporta
um nó de conteúdo.
Modelo de dados
Se você decidir ler as especificações de canonização XML, você notará que tudo
é definido em termos de conjuntos de nós XPath, em que o conjunto de nós contém os nós a serem
convertidos em forma canônica. PHP não possui suporte nativo para canonização para XML,
portanto, usando Xpath depende de como você decide implementar alguma forma de canonização.
Baseado no Modelo de dados XPath, os tipos de nós que são significativos para criar a forma
canônica são raiz, nós de elemento, comentário, PI, texto, atributo e namespace.
Isso não significa que você precisa lidar com outros tipos de nós. Como você já viu, os atributos
precisam ser padronizados, as seções CDATA precisam ser convertidas em nós de texto e as
referências de entidades analisadas e de caractere precisam ser resolvidas. Você pode lidar com eles,
no entanto, enquanto o documento está sendo carregado:
$dom = new DOMDocument();
$dom->loadXML($xmlstring, LIBXML_NOENT | LIBXML_DTDLOAD | LIBXML_DTDATTR |
LIBXML_NOCDATA);
O documento resultante ainda pode conter nós irrelevantes, como uma declaração de tipo de
documento, mas você poderá descartá-los ao criar o formulário canônico.
A ordenação de nós também é importante ao criar a forma canônica. Felizmente, se estiver usando
Xpath, conjuntos de nós já devem estar na ordem do documento, mas para produzir a forma
canônica correta, você precisa lidar com mais alguns problemas:
• Os nós de espaço de nomes vêm antes dos nós de atributo.
• Os nós de namespace são classificados lexicograficamente com base em seus nomes locais, onde
um namespace padrão sempre viria primeiro na lista.
• Os nós de atributo também são classificados lexicograficamente, mas são classificados com base
em seus URIs de namespace e, em seguida, com base em seus nomes locais. Atributos não dentro de
um namespace tem um URI vazio e viria antes de qualquer atributo com namespace.
Isso evita outro desafio que você precisa lidar com a codificação. Se XSL está sendo
usado para criar a saída, o uso criativo de modelos pode ajudar você a conseguir isso.
Você também pode executar isso usando a API do DOM. Embora os atributos não sejam ordenados,
quando serializados, os namespaces são sempre serializados antes dos atributos. Além disso, ambos
são serializados em ordem em que eles são definidos em um elemento. Por exemplo, o primeiro
atributo adicionado ao elemento é o primeiro atributo serializado. O mesmo vale para os
namespaces. O seguinte elemento:
<node a:attr="a-attr" b:attr="b-attr" attr2="attr2" attr="attr"
xmlns:b="http://www.example.com/b"
xmlns:a="http://www.example.com/a"
xmlns="http://www.example.com" />
seria serializado automaticamente para o seguinte:
<node xmlns:b="http://www.example.com/b" xmlns:a="http://www.example.com/a"
xmlns="http://www.example.com" a:attr="a-attr" b:attr="b-attr"
attr2="attr2" attr="attr"/>
Isso ainda não é o que você realmente precisa. As declarações de namespace não são classificadas e
os atributos não são classificados. Usar a API DOM significa recriar a árvore usando apenas
nós apropriados e aplicando todas as regras apropriadas. Neste caso, quando o novo elemento
está sendo criado, namespaces e atributos precisam ser criados na ordem correta. O código
na Listagem 12-1 é apenas um exemplo de como fazer isso. Não é otimizado e dividido
em várias etapas para ilustrar o que precisa acontecer. A variável $ node usada no código
refere-se a um objeto DOMElement que faz referência ao elemento do nó anterior.
Listing12 - 1.SortingNamespaces and Attributes
/* Generic Attribute Sorting And Appending Function */
function sortAndAddAttrs($element, $arAtts)
{
$newAtts = array();
foreach($arAtts AS $attnode) {
$newAtts[$attnode->nodeName] = $attnode;
}
ksort($newAtts);
foreach($newAtts as $attnode) {
$element->setAttribute($attnode->nodeName, $attnode->nodeValue);
}
}
$dom2 = new DOMDocument();
$element = $dom2->createElementNS("http://www.example.com", "node");
$dom2→appendChild($root);
/* Create DOMXPath based on original document $dom */
$xPath = new DOMXPath($dom);
$nsnode = $xPath->query('namespace::*', $node);
/* Add namespace nodes */
foreach($arNS AS $nsnode) {
/* Skip default namespace because it was already added with element node
Skip xml namespace because it is automatic for document */
if ($nsnode->prefix != "" && $nsnode->prefix != "xml") {
$element->setAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" . $nsnode->prefix, $nsnode->namespaceURI);
}
}
/* Get attributes not in a namespace, and then sort and add them */
$arAtts = $xPath->query('attribute::*[namespace-uri(.) = ""]', $node);
sortAndAddAttrs($element, $arAtts);
/* Get namespaced attributes */
$arAtts = $xPath->query('attribute::*[namespace-uri(.) != ""]', $node);
/* Create an array with namespace URIs as keys, and sort them */
$arNS = array();
foreach($arAtts AS $attnode) {
$arNS[$attnode->namespaceURI] = 1;
}
ksort($arNS);
/* Loop through the URIs, and then sort and add attributes within that namespace
*/
foreach($arNS as $nsURI => $val) {
$arAtts = $xPath->query('attribute::*[namespace-uri(.) = "' . $nsURI .
'"]', $node);
sortAndAddAttrs($element, $arAtts);
}
Após a serialização, onde o elemento acabou de ser criado como elemento do documento de
$ dom2, a saída mostra os namespaces e os atributos corretamente ordenados:
<node xmlns="http://www.example.com" xmlns:a="http://www.example.com/a"
xmlns:b="http://www.example.com/b" attr="attr" attr2="attr2"
a:attr="a-attr" b:attr="b-attr"/>
Tradução: Diogo Rocha

Mais conteúdo relacionado

Mais procurados

Introdução à XML - Serviço de Biblioteca da EEFE-USP
Introdução à XML - Serviço de Biblioteca da EEFE-USPIntrodução à XML - Serviço de Biblioteca da EEFE-USP
Introdução à XML - Serviço de Biblioteca da EEFE-USPUniversidade de São Paulo
 
Aplicando Transformação em XML usando XSLT e XSL-FO - 1
Aplicando Transformação em XML usando XSLT e XSL-FO - 1Aplicando Transformação em XML usando XSLT e XSL-FO - 1
Aplicando Transformação em XML usando XSLT e XSL-FO - 1Vivian Motti
 
Aplicando Transformação em XML usando XSLT e XSL-FO - 3
Aplicando Transformação em XML usando XSLT e XSL-FO - 3Aplicando Transformação em XML usando XSLT e XSL-FO - 3
Aplicando Transformação em XML usando XSLT e XSL-FO - 3Vivian Motti
 
Bdm aula 3 - modelo relacional e restrições de integridade
Bdm   aula 3 - modelo relacional e restrições de integridadeBdm   aula 3 - modelo relacional e restrições de integridade
Bdm aula 3 - modelo relacional e restrições de integridadeTicianne Darin
 
Bdm aula 9 - operações sql - ticianne darin
Bdm   aula 9 - operações sql - ticianne darinBdm   aula 9 - operações sql - ticianne darin
Bdm aula 9 - operações sql - ticianne darinTicianne Darin
 
Aplicando Transformação em XML usando XSLT e XSL-FO - 4
Aplicando Transformação em XML usando XSLT e XSL-FO - 4Aplicando Transformação em XML usando XSLT e XSL-FO - 4
Aplicando Transformação em XML usando XSLT e XSL-FO - 4Vivian Motti
 
EXTREME LDAP - GABRIEL STEIN
EXTREME LDAP - GABRIEL STEINEXTREME LDAP - GABRIEL STEIN
EXTREME LDAP - GABRIEL STEINTchelinux
 
Indices B-Tree – considerações básicas
Indices B-Tree – considerações básicasIndices B-Tree – considerações básicas
Indices B-Tree – considerações básicasLuis Marques
 
Migrando de Oracle para PostgreSQL
Migrando de Oracle para PostgreSQLMigrando de Oracle para PostgreSQL
Migrando de Oracle para PostgreSQLFernando Ike
 
A e xtensible markup language (xml)
A e xtensible markup language (xml)A e xtensible markup language (xml)
A e xtensible markup language (xml)Liliana Costa
 

Mais procurados (20)

Introdução à XML - Serviço de Biblioteca da EEFE-USP
Introdução à XML - Serviço de Biblioteca da EEFE-USPIntrodução à XML - Serviço de Biblioteca da EEFE-USP
Introdução à XML - Serviço de Biblioteca da EEFE-USP
 
XML - Introdução
XML - IntroduçãoXML - Introdução
XML - Introdução
 
Aula Xml Schema - XSD
Aula Xml Schema - XSDAula Xml Schema - XSD
Aula Xml Schema - XSD
 
Aplicando Transformação em XML usando XSLT e XSL-FO - 1
Aplicando Transformação em XML usando XSLT e XSL-FO - 1Aplicando Transformação em XML usando XSLT e XSL-FO - 1
Aplicando Transformação em XML usando XSLT e XSL-FO - 1
 
Aplicando Transformação em XML usando XSLT e XSL-FO - 3
Aplicando Transformação em XML usando XSLT e XSL-FO - 3Aplicando Transformação em XML usando XSLT e XSL-FO - 3
Aplicando Transformação em XML usando XSLT e XSL-FO - 3
 
XML & HTML
XML & HTMLXML & HTML
XML & HTML
 
01- Introdução ao XML
01- Introdução ao XML01- Introdução ao XML
01- Introdução ao XML
 
Linguagem SQL
Linguagem SQLLinguagem SQL
Linguagem SQL
 
Ado
AdoAdo
Ado
 
Introdução ao SQL
Introdução ao SQLIntrodução ao SQL
Introdução ao SQL
 
Bdm aula 3 - modelo relacional e restrições de integridade
Bdm   aula 3 - modelo relacional e restrições de integridadeBdm   aula 3 - modelo relacional e restrições de integridade
Bdm aula 3 - modelo relacional e restrições de integridade
 
Bdm aula 9 - operações sql - ticianne darin
Bdm   aula 9 - operações sql - ticianne darinBdm   aula 9 - operações sql - ticianne darin
Bdm aula 9 - operações sql - ticianne darin
 
Sql01
Sql01Sql01
Sql01
 
Sql - introdução
Sql -  introduçãoSql -  introdução
Sql - introdução
 
Aplicando Transformação em XML usando XSLT e XSL-FO - 4
Aplicando Transformação em XML usando XSLT e XSL-FO - 4Aplicando Transformação em XML usando XSLT e XSL-FO - 4
Aplicando Transformação em XML usando XSLT e XSL-FO - 4
 
Xml pucminas2013
Xml pucminas2013Xml pucminas2013
Xml pucminas2013
 
EXTREME LDAP - GABRIEL STEIN
EXTREME LDAP - GABRIEL STEINEXTREME LDAP - GABRIEL STEIN
EXTREME LDAP - GABRIEL STEIN
 
Indices B-Tree – considerações básicas
Indices B-Tree – considerações básicasIndices B-Tree – considerações básicas
Indices B-Tree – considerações básicas
 
Migrando de Oracle para PostgreSQL
Migrando de Oracle para PostgreSQLMigrando de Oracle para PostgreSQL
Migrando de Oracle para PostgreSQL
 
A e xtensible markup language (xml)
A e xtensible markup language (xml)A e xtensible markup language (xml)
A e xtensible markup language (xml)
 

Semelhante a Pro PHP XML e canonização

Semelhante a Pro PHP XML e canonização (20)

Arquitetura: XML + RDF ate WebSemantica
Arquitetura: XML + RDF ate WebSemanticaArquitetura: XML + RDF ate WebSemantica
Arquitetura: XML + RDF ate WebSemantica
 
JustJava 2004: JAXB
JustJava 2004: JAXBJustJava 2004: JAXB
JustJava 2004: JAXB
 
Java e XML
Java e XMLJava e XML
Java e XML
 
Aula Introdução a Linguagem XML
Aula Introdução a Linguagem XMLAula Introdução a Linguagem XML
Aula Introdução a Linguagem XML
 
Tp 4 xml
Tp 4   xmlTp 4   xml
Tp 4 xml
 
xDocLet - Geração de código com xdoclet
xDocLet - Geração de código com xdocletxDocLet - Geração de código com xdoclet
xDocLet - Geração de código com xdoclet
 
Suporte XML nativo no SQL Server 2014/2016
Suporte XML nativo no SQL Server 2014/2016Suporte XML nativo no SQL Server 2014/2016
Suporte XML nativo no SQL Server 2014/2016
 
Aula 10 banco de dados
Aula 10   banco de dadosAula 10   banco de dados
Aula 10 banco de dados
 
Parte5 xml
Parte5 xmlParte5 xml
Parte5 xml
 
Lilacs application profile
Lilacs application  profileLilacs application  profile
Lilacs application profile
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)
 
Plone total#3 Conhecendo o Zope
Plone total#3 Conhecendo o ZopePlone total#3 Conhecendo o Zope
Plone total#3 Conhecendo o Zope
 
Conceitos essenciais de bases de dados
Conceitos essenciais de bases de dadosConceitos essenciais de bases de dados
Conceitos essenciais de bases de dados
 
XML
XMLXML
XML
 
Explicando Estruturas/Registros no C#
Explicando Estruturas/Registros no C#Explicando Estruturas/Registros no C#
Explicando Estruturas/Registros no C#
 
Migrando para o PHP 5
Migrando para o PHP 5Migrando para o PHP 5
Migrando para o PHP 5
 
Aula 10 banco de dados
Aula 10   banco de dadosAula 10   banco de dados
Aula 10 banco de dados
 
JSPs Introdução Parte 1
JSPs Introdução Parte 1JSPs Introdução Parte 1
JSPs Introdução Parte 1
 
JSP: Introdução Parte 1
JSP: Introdução Parte 1JSP: Introdução Parte 1
JSP: Introdução Parte 1
 
Oficina WEB Design Lecom - PHP e MySQL
Oficina WEB Design Lecom - PHP e MySQLOficina WEB Design Lecom - PHP e MySQL
Oficina WEB Design Lecom - PHP e MySQL
 

Pro PHP XML e canonização

  • 1. Livro: Pro PHP XML and Web Services Apresentando o XML Canonical A especificação XML da Canonical (http://www.w3.org/TR/xml-c14n) estabelece um método para determinar se dois documentos são idênticos. O problema subjacente é que podem ser criados documentos que signifiquem a mesma coisa e que tenham o mesmo conteúdo com diferentes representações físicas. Isso dificulta determinar se os dois documentos são realmente idênticos. Com o XML canônico, dois documentos com o mesmo forma canônica são consideradas idênticas, mesmo que suas representações físicas não sejam idênticas. Antes de prosseguir, você deve entender qual é a forma canônica. A especificação define forma canônica de um documento para a representação física do documento criado usando os seguintes métodos: • O documento está codificado em UTF-8. • Quebras de linha normalizam para #xA na entrada, antes da análise. • Valores de atributos são normalizados, como se fosse um processador de validação. • As referências de entidades analisadas e de caractere são substituídas. • As seções CDATA são substituídas pelo conteúdo de seus caracteres. • A declaração XML e a DTD são removidas. • Elementos vazios são convertidos em pares de tag de início e fim. • O espaço em branco fora do elemento do documento e dentro das tags de início e fim é normalizado. • Todo espaço em branco no conteúdo do personagem é retido (excluindo caracteres removidos durante normalização de alimentação de linha). • Os delimitadores de valores de atributos são definidos entre aspas (aspas duplas). • Caracteres especiais em valores de atributos e conteúdo de caracteres são substituídos por caracteres referências. Declarações de espaço de nomes supérfluas são removidas de cada elemento. • Os atributos padrão são adicionados a cada elemento. • A ordem lexicográfica é imposta às declarações e atributos do namespace de cada elemento. Se você olhar através desta lista, você verá alguns itens que tornam as coisas difíceis quando usando PHP para criar XML canônico. Você pode resolver muitos desses problemas usando o analisador opções ao carregar um documento. Usando LIBXML_NOENT, LIBXML_DTDLOAD, LIBXML_DTDATTR, e LIBXML_NOCDATA em combinação irá substituir referências de entidades com seu conteúdo, carregar DTD para garantir que os IDs sejam manipulados, padronize todos os atributos para que eles sejam fisicamente árvore e converta todos os CDATA em conteúdo de texto. Isso deixa alguns itens que não são executados automaticamente. Você poderia manipular o DTD de duas maneiras. Crie um novo documento e faça uma cópia profunda ou importe o elemento do documento para o novo documento. Em seguida, imprima o documento usando o elemento do documento como o contexto ou use XSL. Você também pode lidar com Declaração XML de duas maneiras. Usando o DOM, você pode imprimir o documento usando o elemento documento como o contexto. Ou, usando XSL, supondo que você usou o analisador já mencionado opções, você pode executar uma transformação no documento onde a folha de estilo retorna elemento do documento para a árvore de resultados e omite a declaração XML se estiver sendo serializado. Para exemplo:
  • 2. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output omit-xml-declaration="yes"/> <xsl:template match="/"> <xsl:copy-of select="." /> </xsl:template> </xsl:stylesheet> Se isso for usado para retornar um objeto DOMDocument, a declaração DTD e XML terá sido removido ao serializar usando o elemento document como contexto ao serializar: $root = $doc->documentElement; print $doc->saveXML($root); Nota: A serialização de um documento usando a API do DOM para remover a declaração DTD e XML pode ser feito somente ao serializar para uma string. Serializar para um arquivo não suporta um nó de conteúdo. Modelo de dados Se você decidir ler as especificações de canonização XML, você notará que tudo é definido em termos de conjuntos de nós XPath, em que o conjunto de nós contém os nós a serem convertidos em forma canônica. PHP não possui suporte nativo para canonização para XML, portanto, usando Xpath depende de como você decide implementar alguma forma de canonização. Baseado no Modelo de dados XPath, os tipos de nós que são significativos para criar a forma canônica são raiz, nós de elemento, comentário, PI, texto, atributo e namespace. Isso não significa que você precisa lidar com outros tipos de nós. Como você já viu, os atributos precisam ser padronizados, as seções CDATA precisam ser convertidas em nós de texto e as referências de entidades analisadas e de caractere precisam ser resolvidas. Você pode lidar com eles, no entanto, enquanto o documento está sendo carregado: $dom = new DOMDocument(); $dom->loadXML($xmlstring, LIBXML_NOENT | LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NOCDATA); O documento resultante ainda pode conter nós irrelevantes, como uma declaração de tipo de documento, mas você poderá descartá-los ao criar o formulário canônico. A ordenação de nós também é importante ao criar a forma canônica. Felizmente, se estiver usando Xpath, conjuntos de nós já devem estar na ordem do documento, mas para produzir a forma canônica correta, você precisa lidar com mais alguns problemas: • Os nós de espaço de nomes vêm antes dos nós de atributo. • Os nós de namespace são classificados lexicograficamente com base em seus nomes locais, onde um namespace padrão sempre viria primeiro na lista. • Os nós de atributo também são classificados lexicograficamente, mas são classificados com base em seus URIs de namespace e, em seguida, com base em seus nomes locais. Atributos não dentro de um namespace tem um URI vazio e viria antes de qualquer atributo com namespace. Isso evita outro desafio que você precisa lidar com a codificação. Se XSL está sendo usado para criar a saída, o uso criativo de modelos pode ajudar você a conseguir isso. Você também pode executar isso usando a API do DOM. Embora os atributos não sejam ordenados,
  • 3. quando serializados, os namespaces são sempre serializados antes dos atributos. Além disso, ambos são serializados em ordem em que eles são definidos em um elemento. Por exemplo, o primeiro atributo adicionado ao elemento é o primeiro atributo serializado. O mesmo vale para os namespaces. O seguinte elemento: <node a:attr="a-attr" b:attr="b-attr" attr2="attr2" attr="attr" xmlns:b="http://www.example.com/b" xmlns:a="http://www.example.com/a" xmlns="http://www.example.com" /> seria serializado automaticamente para o seguinte: <node xmlns:b="http://www.example.com/b" xmlns:a="http://www.example.com/a" xmlns="http://www.example.com" a:attr="a-attr" b:attr="b-attr" attr2="attr2" attr="attr"/> Isso ainda não é o que você realmente precisa. As declarações de namespace não são classificadas e os atributos não são classificados. Usar a API DOM significa recriar a árvore usando apenas nós apropriados e aplicando todas as regras apropriadas. Neste caso, quando o novo elemento está sendo criado, namespaces e atributos precisam ser criados na ordem correta. O código na Listagem 12-1 é apenas um exemplo de como fazer isso. Não é otimizado e dividido em várias etapas para ilustrar o que precisa acontecer. A variável $ node usada no código refere-se a um objeto DOMElement que faz referência ao elemento do nó anterior. Listing12 - 1.SortingNamespaces and Attributes /* Generic Attribute Sorting And Appending Function */ function sortAndAddAttrs($element, $arAtts) { $newAtts = array(); foreach($arAtts AS $attnode) { $newAtts[$attnode->nodeName] = $attnode; } ksort($newAtts); foreach($newAtts as $attnode) { $element->setAttribute($attnode->nodeName, $attnode->nodeValue); } } $dom2 = new DOMDocument(); $element = $dom2->createElementNS("http://www.example.com", "node"); $dom2→appendChild($root); /* Create DOMXPath based on original document $dom */ $xPath = new DOMXPath($dom); $nsnode = $xPath->query('namespace::*', $node); /* Add namespace nodes */ foreach($arNS AS $nsnode) { /* Skip default namespace because it was already added with element node Skip xml namespace because it is automatic for document */ if ($nsnode->prefix != "" && $nsnode->prefix != "xml") { $element->setAttributeNS("http://www.w3.org/2000/xmlns/",
  • 4. "xmlns:" . $nsnode->prefix, $nsnode->namespaceURI); } } /* Get attributes not in a namespace, and then sort and add them */ $arAtts = $xPath->query('attribute::*[namespace-uri(.) = ""]', $node); sortAndAddAttrs($element, $arAtts); /* Get namespaced attributes */ $arAtts = $xPath->query('attribute::*[namespace-uri(.) != ""]', $node); /* Create an array with namespace URIs as keys, and sort them */ $arNS = array(); foreach($arAtts AS $attnode) { $arNS[$attnode->namespaceURI] = 1; } ksort($arNS); /* Loop through the URIs, and then sort and add attributes within that namespace */ foreach($arNS as $nsURI => $val) { $arAtts = $xPath->query('attribute::*[namespace-uri(.) = "' . $nsURI . '"]', $node); sortAndAddAttrs($element, $arAtts); } Após a serialização, onde o elemento acabou de ser criado como elemento do documento de $ dom2, a saída mostra os namespaces e os atributos corretamente ordenados: <node xmlns="http://www.example.com" xmlns:a="http://www.example.com/a" xmlns:b="http://www.example.com/b" attr="attr" attr2="attr2" a:attr="a-attr" b:attr="b-attr"/> Tradução: Diogo Rocha