在 PHP 中解析 XSD 文件并显示 XSD 中的元素

Posted

技术标签:

【中文标题】在 PHP 中解析 XSD 文件并显示 XSD 中的元素【英文标题】:Parse XSD file in PHP and display the elements in the XSD 【发布时间】:2013-11-14 09:28:23 【问题描述】:

我有一个 XSD 模式文件,我想解析和回显它包含的元素,如果可能的话,还可以显示每个元素的子元素。我看过一些例子,其中最好的例子有: Convert XSD file into array in php

我试过了,即使更改了 xpaths 中的 xs: 部分和文件位置,它也给了我一个空数组。有没有正确的方法来解析 XSD 文件并在 PHP 中显示其元素?

为了消除任何困惑,我想说的是:

假设这是我正在尝试加载和显示其元素的 XSD(来自上面的链接):

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="shiporder">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="orderperson" type="xs:string"/>
      <xs:element name="shipto">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="address" type="xs:string"/>
            <xs:element name="city" type="xs:string"/>
            <xs:element name="country" type="xs:string"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="item" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="title" type="xs:string"/>
            <xs:element name="note" type="xs:string" minOccurs="0"/>
            <xs:element name="quantity" type="xs:positiveInteger"/>
            <xs:element name="price" type="xs:decimal"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="orderid" type="xs:string" use="required"/>
  </xs:complexType>
</xs:element>

</xs:schema>

我们可以看到有一个名为“shiporder”的元素,它有子元素,如果我没记错的话,“orderperson”的类型是字符串,它还有“shipto”,子元素是: "name", "address", "city", "country" 是字符串类型。

我想要做的只是简单地打印出“shiporder”有孩子“orderperson”和“shipto”“shipto”有孩子“name”、“address”、“city”和“country”。

我怎样才能做到这一点?我应该使用下面描述的方法吗?:

<?php 
$attributes = array(); 
$xsdstring = "test.xsd"; 
$XSDDOC = new DOMDocument(); 
$XSDDOC->preserveWhiteSpace = false; 
if ($XSDDOC->load($xsdstring)) 
 
    $xsdpath = new DOMXPath($XSDDOC); 
    $attributeNodes = 
              $xsdpath-> 
              query('//xs:element[@name="shiporder"]')
              ->item(0); 
    foreach ($attributeNodes->childNodes as $attr) 
     
        $attributes[ $attr->getAttribute('value') ] = $attr->getAttribute('name'); 
     
    unset($xsdpath); 
 
print_r($attributes); 
?>

希望这能让我的问题更清楚一些,因为我是 php 和 xml 解析的新手。

【问题讨论】:

你试过XSD-to-PHP吗? 还没有,我希望有一种简单的方法可以做到这一点,无需任何额外的软件。 这其实不是我要找的,我只是想拿一个xsd并打印出xsd中的元素 "elements of the xsd" 是模棱两可的,因为 XSD 本身就是一个 XML 文档。您想要 XSD 中使用的所有元素名称来定义架构,还是想要 XSD 允许在其管理的 XML 实例中使用的所有元素名称?此外,您确实应该通过在此处包含您的代码来展示您尝试过的内容,而不仅仅是一个链接和一些关于您所做更改的散文。否则,您可能会面临关闭问题的风险。谢谢。 我已经更新了问题以尝试解决问题 【参考方案1】:

这个 PHP:

<?php 

$xsdstring = <<<XML
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="shiporder">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="orderperson" type="xs:string"/>
        <xs:element name="shipto">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="name" type="xs:string"/>
              <xs:element name="address" type="xs:string"/>
              <xs:element name="city" type="xs:string"/>
              <xs:element name="country" type="xs:string"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="item" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="title" type="xs:string"/>
              <xs:element name="note" type="xs:string" minOccurs="0"/>
              <xs:element name="quantity" type="xs:positiveInteger"/>
              <xs:element name="price" type="xs:decimal"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="orderid" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>
XML;

$doc = new DOMDocument();
$doc->loadXML(mb_convert_encoding($xsdstring, 'utf-8', mb_detect_encoding($xsdstring)));
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('xs', 'http://www.w3.org/2001/XMLSchema');

function echoElements($indent, $elementDef) 
  global $doc, $xpath;
  echo "<div>" . $indent . $elementDef->getAttribute('name') . "</div>\n";
  $elementDefs = $xpath->evaluate("xs:complexType/xs:sequence/xs:element", $elementDef);
  foreach($elementDefs as $elementDef) 
    echoElements($indent . "&nbsp;&nbsp;&nbsp;&nbsp;", $elementDef);
  


$elementDefs = $xpath->evaluate("/xs:schema/xs:element");
foreach($elementDefs as $elementDef) 
  echoElements("", $elementDef);
                       
?>

产生以下输出:

shiporder
    orderperson
    shipto
        name
        address
        city
        country
    item
        title
        note
        quantity
        price

根据要求。

请注意,这假定一个简单的 Russian Doll XSD design 使用基本的嵌入式 xs:complexType/xs:sequence/ 结构,如提供的 shiporder 定义及其后代元素中所示。

【讨论】:

谢谢工作,我只是不喜欢那里使用的全局变量,令人惊讶的是 php 不支持解析 xsd 文档,因为它也只是一种 xml @FantomX1:PHP 确实支持将 XSD 解析为 XML,如本答案所示。演示/代码 sn-p 中的“全局”变量不应该打扰您;很容易按纽扣上工作代码——这只是一个让人们开始或摆脱困境的演示。 是的,upvoded,也许我最初删除了一个投票,直到我让 sn-p 为自己工作,所以我必须等待延迟直到下一次允许的投票更改:) 但至少我赞成你的评论,通过您可能不知道如何通过属性“名称”进行 xpath,尽管我想我会在这里使用 google

以上是关于在 PHP 中解析 XSD 文件并显示 XSD 中的元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 php 针对 xsd 验证 xml 文件

如何在 php 页面中显示 XML 外部实体?

是否可以使用 Qt(不使用 XSD 工具)从 xsd 生成 C++ 类?

Infopath入门到精通系列-4 Infopath myschema.xsd文件 解析

Maven Xjc / Jaxb插件无法解析简单的Xsd文件

如何在 Java DocumentBuilder 中解析 XSD 文件期间将元素附加到现有节点列表