使用多个命名空间创建 XML 时的冗余 XMLNS 属性

问题描述 投票:0回答:1

我的代码:

$xmlns = [
    'xmlns' => 'http://www.w3.org/2000/xmlns/',
    'rsm' => 'urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100',
    'ram' => 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100',
    'qdt' => 'urn:un:unece:uncefact:data:Standard:QualifiedDataType:100',
    'udt' => 'urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100',
    'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
];

$document = new DOMDocument();
$root = $document->createElementNS($xmlns['rsm'], 'rsm:CrossIndustryInvoice');
$root->setAttributeNS($xmlns['xmlns'], 'xmlns:ram', $xmlns['ram']);
$root->setAttributeNS($xmlns['xmlns'], 'xmlns:qdt', $xmlns['qdt']);
$root->setAttributeNS($xmlns['xmlns'], 'xmlns:udt', $xmlns['udt']);
$root->setAttributeNS($xmlns['xmlns'], 'xmlns:xsi', $xmlns['xsi']);
$document->appendChild($root);

$parent = $document->createElementNS($xmlns['rsm'], 'ExchangedDocumentContext');
$sub = $document->createElementNS($xmlns['ram'], 'GuidelineSpecifiedDocumentContextParameter');
$child = $document->createElementNS($xmlns['ram'], 'ID', 'urn:cen.eu:en16931:2017');
$sub->appendChild($child);
$parent->appendChild($sub);
$root->appendChild($parent);

$parent = $document->createElementNS($xmlns['rsm'], 'ExchangedDocument');
$child = $document->createElementNS($xmlns['ram'], 'ID', 'LoremIpsum');
$parent->appendChild($child);
$root->appendChild($parent);

return $document->saveXML();

我得到的结果:

<?xml version="1.0"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100">
      <ram:ID>urn:cen.eu:en16931:2017</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100">LoremIpsum</ram:ID>
  </rsm:ExchangedDocument>
</rsm:CrossIndustryInvoice>

我期望的结果:

<?xml version="1.0"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>LoremIpsum</ram:ID>
  </rsm:ExchangedDocument>
</rsm:CrossIndustryInvoice>

为什么子元素中有这些额外的 XML 命名空间定义?我知道,我可以使用

createElement('ram:GuidelineSpecifiedDocumentContextParameter');
代替
createElementNS($xmlns['ram'], 'GuidelineSpecifiedDocumentContextParameter');
,但这感觉不好或不对。 如何正确地做到这一点,但仍然摆脱这些名称空间重新声明?

php xml domdocument xml-namespaces
1个回答
0
投票

我的错误。原因在于元素插入 XML 的顺序。更改现有代码时:

$parent = $document->createElementNS($xmlns['rsm'], 'ExchangedDocumentContext');
$sub = $document->createElementNS($xmlns['ram'], 'GuidelineSpecifiedDocumentContextParameter');
$child = $document->createElementNS($xmlns['ram'], 'ID', 'urn:cen.eu:en16931:2017');
$sub->appendChild($child);
$parent->appendChild($sub);
$root->appendChild($parent);

至:

$parent = $document->createElementNS($xmlns['rsm'], 'ExchangedDocumentContext');
$root->appendChild($parent);
$sub = $document->createElementNS($xmlns['ram'], 'GuidelineSpecifiedDocumentContextParameter');
$parent->appendChild($sub);
$child = $document->createElementNS($xmlns['ram'], 'ID', 'urn:cen.eu:en16931:2017');
$sub->appendChild($child);

我得到了我想要的。请注意更改:我没有准备整个节点树并将其至少附加到根,而是立即将新创建的元素附加到 DOM 树。

© www.soinside.com 2019 - 2024. All rights reserved.