【问题标题】:Xpath get all children with the given anchorXpath 获取所有具有给定锚点的子节点
【发布时间】:2013-12-19 09:32:20
【问题描述】:

我有一个 XML 文件,其中包含很多这样的行:

<class name="CustomerProfileLite" inList="true" >
    <enum name="Order" takeOtherValuesFromProperties="true">
        <value>None</value>
    </enum>
    <property name="Guid" type="guid" />
    <property name="CreationDate" type="datetime" isInEnum="true" />
    <property name="LastUpdateDate" type="datetime" isIndexed="true" isInEnum="true" />
    <property name="Revision" type="int" isIndexed="true" isInEnum="true" />
    <property name="Thumbnail" type="string" convertToRelativePathInDB="true" />
    <property name="UmsJob" type="string" isIndexed="true"/>
    <property name="FirstName" type="string" isIndexed="true" isInEnum="true" />
    <property name="LastName" type="string" isIndexed="true" isInEnum="true" />
    <property name="Address" type="string" isInEnum="true" />
    <property name="City" type="string" isInEnum="true" />
    <property name="PhoneNumber" type="string" isIndexed="true" isInEnum="true" />
    <property name="CellPhoneNumber" type="string" isIndexed="true" isInEnum="true" />
    <property name="Birthdate" type="OptionalDateTime" isInEnum="true" />
    <property name="HasFrames" type="bool" />
    <property name="LatestEquipementHasFarVisionBoxings" type="bool" />
    <property name="LatestEquipementHasFarVisionImages" type="bool" />
    <property name="LatestEquipementHasSplines" type="bool" />
    <property name="LatestEquipementHasIpadMeasure" type="bool" />
    <sattribute name="IsModified" type="bool" />
    <sattribute name="LastModificationDate" type="datetime" />
</class>

我需要获取类名及其所有属性。我还需要将所有枚举值存储在不同的数组中。

我编写了以下代码,但无法使其正常工作。我无法获取 property 孩子和 enum 列表。

$this->struct_xml =  simplexml_load_file("assets/archi.xml");
$archi = array();
$types = $this->struct_xml->xpath("type");
foreach ($types as $type) {
    $name = (string) $type['name'];
    $archi[$name] = array();

    if ((bool) $type['isComplexType']) {
        $class = first($this->struct_xml->xpath("class[@name='$name']"));
        if (!$class) throw new Exception("Unknown type found $name !");

        foreach ($class->children('property') as $property) {
            $archi[$name]['children'][] = array(
                'name' => (string) $property['name'],
                'type' => (string) $property['type'],
            );
        }
    }
}

$enums = $this->struct_xml->xpath("enum");
foreach ($enums as $enum) {
    $name = (string) $type['name'];
    $archi[$name] = array();
    foreach ($enum->children() as $value) {
        $archi[$name]['values'][] = $value;
    }
}

$class-&gt;children('property') 行返回一个空的SimpleXMLElement$this-&gt;struct_xml-&gt;xpath("enum") 行也返回一个空值,而它应该给我一个枚举列表。

你能帮我解决它吗?

【问题讨论】:

  • $class-&gt;children('property') 应该是$class-&gt;propertyxpath("enum") 应该是 xpath("//enum")

标签: php xml xpath xml-parsing


【解决方案1】:

$class-&gt;children('property') 行返回一个空的SimpleXMLElement

虽然SimpleXMLElement::children()指的是当前元素的子元素,但它的第一个参数是命名空间,而不是标签名。

所以$class-&gt;children('property') 意味着检查$class 中的子元素是否在命名空间property

您可以只使用$class-&gt;property 来检索该类中所有&lt;property&gt; 标记的“列表”;


$this-&gt;struct_xml-&gt;xpath("enum") 行返回一个空值,而它应该给我一个枚举列表

XPath 不像 HTML DOM 中的 document.getElementByTagName。您至少必须指定标签是某物的子项。懒惰的形式是xpath("//enum")


Here is a simple demo

$dom=simplexml_load_file("xml");
foreach($dom->xpath("//class") as $class)
{
    echo (string)$class["name"];
    echo "\n";
    foreach($class->property as $property)
    {
        echo (string)$property["name"];
        echo "\t";
        echo (string)$property["type"];
        echo "\n";
    }
}
foreach($dom->xpath("//enum") as $enum)
{
    echo (string)$enum["name"];
    echo "\t";
    echo (string)$enum->value;
}

输出:

CustomerProfileLite
Guid    guid
CreationDate    datetime
LastUpdateDate  datetime
Revision    int
...
Order   None

【讨论】:

    【解决方案2】:

    SimpleXML::children 的参数用于获取具有特定命名空间前缀的子代。您必须直接指向该节点。例如:

    $class->property->children()
    

    有关命名空间和前缀的更多信息,请查看http://www.w3schools.com/xml/xml_namespaces.asp

    【讨论】:

      【解决方案3】:

      请尝试使用此代码打印您的数据,并在该循环中添加条件,

      $this_struct_xml =  simplexml_load_file("archi.xml"); //$this->struct_xml = $struct_xml;
      foreach($this_struct_xml->property as $property) { 
          echo "name:".$property->attributes()->name." / ";
          echo "type:".$property->attributes()->type." / ";
          echo "isInEnum:".$property->attributes()->isInEnum." / ";
          echo "isIndexed:".$property->attributes()->isIndexed."<br/>";
      }
      
      echo "-------------------------------<br/>";
      
      foreach($this_struct_xml->enum as $enum) { 
          echo "name:".$enum->attributes()->name." / ";
          echo "type:".$enum->attributes()->takeOtherValuesFromProperties." / ";
          echo "Value:".$enum->value."<br/>";
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多