friendsofcxml/cxml-php

cXML标准的PHP实现

2.0RC2 2024-09-17 11:32 UTC

README

cXML是一个旨在用于采购应用程序、电子商务中心和供应商之间一致通信业务文档的简化协议。http://cxml.org/

cXML参考指南(PDF):http://xml.cxml.org/current/cXMLReferenceGuide.pdf

状态

入门

安装

$ composer require friendsofcxml/cxml-php

然后包含Composer的自动加载器

require_once 'vendor/autoload.php';

获取当前的DTD定义文件

  1. http://cxml.org/downloads.html下载当前规范
  2. 提取文件
  3. 使用cXML.dtd进行验证(见下文)

快速入门

身份和凭证

//we use a basic registry here. You could use your own (db-based?) repository that implements CredentialRepositoryInterface
$credentialRegistry = new \CXml\Credential\Registry();

$someSupplier = new \CXml\Model\Credential('DUNS', 12345);
$credentialRegistry->registerCredential($someSupplier);

$someBuyer = new \CXml\Model\Credential('my-id-type', "buyer@domain.com");
$credentialRegistry->registerCredential($someBuyer);

$someHub = new \CXml\Model\Credential('my-id-type', "hub@domain.com", "abracadabra");
$credentialRegistry->registerCredential($someHub);

注册处理器

$handlerRegistry = new \CXml\Handler\HandlerRegistry();

$handlerRegistry->register(new CXml\Handler\Request\SelfAwareProfileRequestHandler(...));
$handlerRegistry->register(new CXml\Handler\Request\StaticStartPagePunchOutSetupRequestHandler(...));
$handlerRegistry->register(new MyOrderRequestHandler());
$handlerRegistry->register(new MyStatusUpdateRequestHandler());
...

构建cXML

//$payload = new \CXml\Model\Message\...Message(...);
//or...
//$payload = new \CXml\Model\Request\...Request(...);
//or...
$payload = new \CXml\Model\Response\...Response(...);

$cXml = \CXml\Builder::create()
    ->payload($payload)
    ->build();

$payload = new \CXml\Model\Request\...Request(...);
$cXml = \CXml\Builder::create()
    ->payload($payload)
    ->from(...)
    ->to(...)
    ->sender(...)
    ->build();

注册出站cXML文档

您可能希望注册已发送的文档,以便后续请求文档可以通过payloadId引用。

$documentRegistory = new MyDocumentRegistry(); //implements CXml\Document\DocumentRegistryInterface

$documentRegistory->register($cXml);

处理传入的cXML文档

$headerProcessor = new \CXml\Processor\HeaderProcessor($credentialRegistry, $credentialRegistry);

$cXmlProcessor = new \CXml\Processor\Processor(
  $headerProcessor, 
  $handlerRegistry,
  $builder
);

$cXmlProcessor->process($cXml);

整合一切

$credentialRegistry = new \CXml\Credential\Registry();
//TODO register...

$handlerRegistry = new \CXml\Handler\HandlerRegistry();
//TODO register...

$builder = \CXml\Builder::create();

$headerProcessor = new \CXml\Processor\HeaderProcessor($credentialRegistry, $credentialRegistry);
$cXmlProcessor = new \CXml\Processor\Processor(
  $headerProcessor, 
  $handlerRegistry,
  $builder
);

$pathToDtd = '.'; //point the directory with extracted contents of zip-file with the DTDs, downloaded from cxml.org
$dtdValidator = new \CXml\Validation\DtdValidator($pathToDtd);

$endpoint = new \CXml\Endpoint(
    $dtdValidator,
    $cXmlProcessor
);

//$xmlString could be the body of an incoming http request
$xmlString = '<cXML>...</cXML>';
$result = $endpoint->parseAndProcessStringAsCXml($xmlString);

//$result could be null (i.e. for a Response or Message) or another CXml object which would be the Response to a Request
//you would have to handle the transport yourself

处理日期与DateTime

cXML规范对日期和时间的格式并不完全明确。规范表示,日期应格式化为“ISO 8601的受限子集”。这意味着格式可以是包含时间和时区信息(即2015-04-14T13:36:00-08:00)的完整ISO 8601格式,也可以是不包含时间和时区的格式(2015-04-14)。

对于某些字段,一天中的实际时间并不重要,可能会导致混淆。例如,在ItemOut中的requestedDeliveryDate字段。实际经验表明,这里通常只指定日期。尽管有人可能会争论,对于严格意义上的即时交付,一天中的时间仍然是相关的。

为了解决这个问题,我们引入了一个确定的CXml\Model\Date类,用于使用显式日期(不包含时间)。该类扩展了DateTime,因此与其他模型兼容。该类强制执行只包含日期的表示(Y-m-d)。

序列化

当生成对象图并希望输出只包含日期的值时,应使用CXml\Model\Date类。

反序列化

在从cXML文档解析日期属性时,如果发现了只包含日期的值(Y-m-d),则会实例化CXml\Model\Date

致谢