dongmao3148 2013-12-19 09:32
浏览 37
已采纳

Xpath获取具有给定锚点的所有子项

I got a XML file which contains a lot of lines like that:

<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>

I need to get the class name and all it's properties. I also need to store all the enum values in a different array.

I've made the following code but I can't make it work properly. I can't get the property children and the enum list.

$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;
    }
}

The line $class->children('property') returns an empty SimpleXMLElement. Also the line $this->struct_xml->xpath("enum") returns a null value whereas it should give me a list of enum.

Could you help me to fix it ?

  • 写回答

3条回答 默认 最新

  • duanhui7329 2013-12-19 10:02
    关注

    The line $class->children('property') returns an empty SimpleXMLElement

    While SimpleXMLElement::children() refers to the children of the current element, its first parameter is to indicate namespace, not tag name.

    So $class->children('property') means to check for child element in $class that is in namespace property.

    You can just use $class->property to retrieve a "list" of all <property> tag inside that class;


    the line $this->struct_xml->xpath("enum") returns a null value whereas it should give me a list of enum

    XPath is not like document.getElementByTagName in HTML DOM. You have to at least specify that the tag is a child of something. The lazy form would be xpath("//enum").


    Here is a simple demo:

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

    Outputs:

    CustomerProfileLite
    Guid    guid
    CreationDate    datetime
    LastUpdateDate  datetime
    Revision    int
    ...
    Order   None
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题
  • ¥50 如何将脑的图像投影到颅骨上