带有默认名称空间声明的SimpleXML根节点前缀php

00jrzges  于 2022-12-17  发布在  PHP
关注(0)|答案(2)|浏览(123)

我正在用PHP创建一个xml文件。我需要创建的文件如下所示:

<p:FatturaElettronica versione="FPA12" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:p="http://microsoft.com/wsdl/types/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versione="FPA12" >
 <FatturaElettronicaHeader>
  <DatiTrasmissione>
   <IdTrasmittente>
    <IdPaese>IT</IdPaese>
    <IdCodice>01234567890</IdCodice>
   </IdTrasmittente>
   <ProgressivoInvio>00001</ProgressivoInvio>
   <FormatoTrasmissione>FPA12</FormatoTrasmissione>
   <CodiceDestinatario>AAAAAA</CodiceDestinatario>
  </DatiTrasmissione>
  </FatturaElettronicaHeader>
<p:FatturaElettronica>

这是我的代码:

$xml = new SimpleXMLElement('<p:FatturazioneElettronica xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:p="http://microsoft.com/wsdl/types/" />');
$xml->addAttribute("versione","FPA12");
$xml->addAttribute("xmlns:xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
$FatturaElettronicaHeader = $xml->addChild('FatturaElettronicaHeader');
$DatiTrasmissione=$FatturaElettronicaHeader->addChild('DatiTrasmissione');
$IdTrasmittente=$DatiTrasmissione->addChild('IdTrasmittente');
$IdTrasmittente->addChild('IdPaese', 'IT');
$IdTrasmittente->addChild('IdCodice','01234567890');

$ProgressivoInvio=$DatiTrasmissione->addChild('ProgressivoInvio', '00001');
$FormatoTrasmissione=$DatiTrasmissione->addChild('DatiTrasmissione', 'FPA12');
$CodiceDestinatario=$DatiTrasmissione->addChild('CodiceDestinatario', 'AAAAAA');

因为在我创建的文件中,我最初的前缀是p:在每个标记中,如下所示

<p:FatturazioneElettronica xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:p="http://microsoft.com/wsdl/types/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versione="FPA12">
 <p:FatturaElettronicaHeader>
   <p:DatiTrasmissione>
    <p:IdTrasmittente>
     <p:IdPaese>IT</p:IdPaese>
     <p:IdCodice>01234567890</p:IdCodice>
    </p:IdTrasmittente>
    <p:ProgressivoInvio>00001</p:ProgressivoInvio>
   <p:DatiTrasmissione>FPA12</p:DatiTrasmissione>
   <p:CodiceDestinatario>AAAAAA</p:CodiceDestinatario>
 </p:DatiTrasmissione>

而这个前缀P:必须仅位于根节点(p:FatturaElettronica)中我添加了xmlns="http://dummy.com"

<p:FatturazioneElettronica xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:p="http://microsoft.com/wsdl/types/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versione="FPA12" xmlns="http://dummy.com">

以及

$fatturaelettronicaheader = $xml->addChild('FatturaElettronicaHeader', '', 'http://dummy.com');

正如在此question中所建议的
只有"dummy.com“**不存在于原始xml文件中。
如何解决这个问题,或者在实际生成文件之前消除它?

wh6knrhe

wh6knrhe1#

SimpleXML抽象了节点,并为名称空间提供了一些自动逻辑,这对于基本/简单的XML结构来说非常有效。
对于更复杂的XML结构,你需要显式的--所以使用DOM。它有针对不同节点类型的特定方法,有名称空间和没有名称空间。

// define a list with the used namespaces
$namespaces = [
  'xmlns' => 'http://www.w3.org/2000/xmlns/',
  'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
  'signature' => 'http://www.w3.org/2000/09/xmldsig#',
  'wsdl-types' => 'http://microsoft.com/wsdl/types/'
];

$document = new DOMDocument('1.0', 'UTF-8');
// create and append an element with a namespace
// this will add the namespace definition for the prefix "p" also
$document->appendChild(
    $root = $document->createElementNS($namespaces['wsdl-types'], 'p:FatturazioneElettronica')
);
// set an attribute without a namespace
$root->setAttribute('versione', 'FPA12');
// add namespace definitions using the reserved "xmlns" namespace
$root->setAttributeNS($namespaces['xmlns'], 'xmlns:xsi', $namespaces['xsi']);
$root->setAttributeNS($namespaces['xmlns'], 'xmlns:ds', $namespaces['signature']);

// create and append the an element - keep in variable for manipulation
// the element does not have a namespace
$root->appendChild(
    $header = $document->createElement('FatturaElettronicaHeader')    
);
$header->appendChild(
    $dati = $document->createElement('DatiTrasmissione')
);

$dati->appendChild(
    $id = $document->createElement('IdTrasmittente')
);

// create and append element, set text content using a chained call 
$id
    ->appendChild($document->createElement('IdPaese'))
    ->textContent = 'IT';
$id
    ->appendChild($document->createElement('IdCodice'))
    ->textContent = '01234567890';
  
$dati
    ->appendChild($document->createElement('ProgressivoInvio'))
    ->textContent = '00001';
$dati
    ->appendChild($document->createElement('FormatoTrasmissione'))
    ->textContent = 'FPA12';
$dati
    ->appendChild($document->createElement('CodiceDestinatario'))
    ->textContent = 'AAAAAA';

$document->formatOutput = TRUE;
echo $document->saveXML();

输出:

<?xml version="1.0" encoding="UTF-8"?>
<p:FatturazioneElettronica xmlns:p="http://microsoft.com/wsdl/types/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" versione="FPA12">
  <FatturaElettronicaHeader>
    <DatiTrasmissione>
      <IdTrasmittente>
        <IdPaese>IT</IdPaese>
        <IdCodice>01234567890</IdCodice>
      </IdTrasmittente>
      <ProgressivoInvio>00001</ProgressivoInvio>
      <FormatoTrasmissione>FPA12</FormatoTrasmissione>
      <CodiceDestinatario>AAAAAA</CodiceDestinatario>
    </DatiTrasmissione>
  </FatturaElettronicaHeader>
</p:FatturazioneElettronica>

注意在XML中p:FatturazioneElettronica有一个名称空间,它解析为{http://microsoft.com/wsdl/types/}FatturazioneElettronica,但是我不认为FatturazioneElettronica是WSDL类型名称空间中的有效元素。
FatturaElettronicaHeader(以及后代节点)没有命名空间。

kx5bkwkv

kx5bkwkv2#

首先,您想要的XML(以及您链接到的问题中的XML)格式不好,原因有几个。
其次,即使在这一点得到解决(见下文),我也不清楚你为什么要这样做。
不如这样:

$string = '<?xml version="1.0" encoding="UTF-8"?>
<root>
   <p:FatturaElettronica xmlns:p="http://microsoft.com/wsdl/types/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versione="FPA12">
      <FatturaElettronicaHeader>
         <DatiTrasmissione>
            <IdTrasmittente>
               <IdPaese>IT</IdPaese>
               <IdCodice>01234567890</IdCodice>
            </IdTrasmittente>
            <ProgressivoInvio>00001</ProgressivoInvio>
            <FormatoTrasmissione>FPA12</FormatoTrasmissione>
            <CodiceDestinatario>AAAAAA</CodiceDestinatario>
         </DatiTrasmissione>
      </FatturaElettronicaHeader>
   </p:FatturaElettronica>
</root>';                                                                       
$xml = simplexml_load_string($string);

echo $xml->asXML() ."\r\n";

这应该与格式良好的xml相呼应。

相关问题