使用PHP将XML模式默认注入到文档中

时间:2013-04-11 12:31:08

标签: php xml xsd default-value

这里我们有一个简单的XML模式:

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="item">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="item" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
            <xs:attribute name="is-foo" type="xs:boolean" default="true" use="optional" />
            <xs:attribute name="is-bar" type="xs:boolean" default="false" use="optional" />
        </xs:complexType>
    </xs:element>
</xs:schema>

具有可选<item> / is-foo布尔属性的递归is-bar节点,分别默认为truefalse

现在,在PHP中读取XML数据的上下文中,这些默认值有用吗?如果我有一个有效的XML文档:

<item is-foo="false" is-bar="false">
    <item is-bar="true">
        <item>
            <item is-foo="true">
                <item />
                <item is-foo="true" />
            </item>
        </item>
        <item is-foo="true" is-bar="true" />
    </item>
</item>

我跑的是:

$document = new DOMDocument();
$document->load('./test.xml');
var_dump($document->schemaValidate('./test.xsd'));

$xpath = new DOMXPath($document);
foreach ($xpath->query('//item') as $item) {
    echo $item->getNodePath() . PHP_EOL
        . '  is-foo : ' . $item->getAttribute('is-foo') . PHP_EOL
        . '  is-bar : ' . $item->getAttribute('is-bar') . PHP_EOL;
}

我得到以下输出(,虽然预计是不幸的):

bool(true)
/item
  is-foo : false
  is-bar : false
/item/item
  is-foo :
  is-bar : true
/item/item/item[1]
  is-foo :
  is-bar :
/item/item/item[1]/item
  is-foo : true
  is-bar :
/item/item/item[1]/item/item[1]
  is-foo :
  is-bar :
/item/item/item[1]/item/item[2]
  is-foo : true
  is-bar :
/item/item/item[2]
  is-foo : true
  is-bar : true

这里的问题是所有空属性值。

除了以编程方式将默认值注入文档(,这需要解释模式以获得任何可重用性),是否有任何选项可以将XML文档转换为包含相应模式中定义的默认值?

1 个答案:

答案 0 :(得分:3)

DOM扩展目前无法实现。

除非在使用的架构验证上下文中设置了XML_SCHEMA_VAL_VC_I_CREATE,并且当前it isn't,否则libxml不会这样做。

我已经创建了patch,希望通过$flags / schemaValidate()的新schemaValidateSource()参数以及新的LIBXML_SCHEMA_CREATE来展示此功能常量(example target code),但我还没有测试它,因为我没有可用的构建环境。

修改

补丁现在已经过测试,我创建了PR以合并到5.5分支。

编辑2

PR现已合并为master,该功能应该可以从PHP 5.5.2获得。

编辑3

See it working