使用SimpleXMLElement获取未知元素名称的Xpath表达式

时间:2013-11-05 23:47:27

标签: php xml xpath simplexml expression

Iam尝试编写一个xpath表达式,根据一些标准从xml中获取元素名称。

之后的事情是获取具有子节点“fields / enable”的每个元素的元素名称列表。我不知道元素的名称是什么,我没有触发的任何属性,元素可以是任何xml可接受的名称。

在示例中,我对以下结果感兴趣:

ajob
bjob
cjob 

我设法了解了我感兴趣的每个节点的标签名称。在这个例子中,标签名称与我想要的元素名称完全相同,但我不能依赖于标签不会被更改。我唯一确定的是元素名称。

->xpath("//wrapper/groups/*/fields/enable/../../label");

我在这上面谷歌并获得了几个点击使用不同的名称()使用组合。我从未设法获得任何让name()返回任何值的尝试。

->xpath("//wrapper/groups/*/fields//enable/../name(parent::*)");

->xpath("name(//wrapper/groups/*/fields/enable/../..)");

我已经简化了下面的XML示例,但基本结构和感兴趣的元素仍然存在

我会感谢任何帮助。

<?xml version="1.0" encoding="UTF-8"?>
<config>
   <wrapper>
      <groups>
         <ainfo>
            <label>Information</label>
         </ainfo>
         <atimer>
            <label>Schedule</label>
            <fields>
               <time />
               <frequency />
            </fields>
         </atimer>
         <ajob>
            <label>ajob</label>
            <fields>
               <enable>1</enable>
            </fields>
         </ajob>
         <btimer>
            <label>Schedule</label>
            <fields>
               <time />
               <frequency />
            </fields>
         </btimer>
         <bjob>
            <label>bjob</label>
            <fields>
               <enable>1</enable>
            </fields>
         </bjob>
         <cinfo>
            <label>Information</label>
         </cinfo>
         <cjob>
            <label>cjob</label>
            <fields>
               <enable>1</enable>
            </fields>
         </cjob>
      </groups>
   </wrapper>
</config>

3 个答案:

答案 0 :(得分:1)

对于使用PHP,SimpleXML的给定XML here's a working solution以及对您提供的//wrapper/groups/*/fields/enable/../../label XPath表达式的微小更改:

<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<config>
   <wrapper>
      <groups>
         <ainfo>
            <label>Information</label>
         </ainfo>
         <atimer>
            <label>Schedule</label>
            <fields>
               <time />
               <frequency />
            </fields>
         </atimer>
         <ajob>
            <label>ajob</label>
            <fields>
               <enable>1</enable>
            </fields>
         </ajob>
         <btimer>
            <label>Schedule</label>
            <fields>
               <time />
               <frequency />
            </fields>
         </btimer>
         <bjob>
            <label>bjob</label>
            <fields>
               <enable>1</enable>
            </fields>
         </bjob>
         <cinfo>
            <label>Information</label>
         </cinfo>
         <cjob>
            <label>cjob</label>
            <fields>
               <enable>1</enable>
            </fields>
         </cjob>
      </groups>
   </wrapper>
</config>
XML;

$sxe           = new SimpleXMLElement($xml);
$enabledLabels = $sxe->xpath('//wrapper/groups/*/fields/enable[.=1]/../../label');

foreach ($enabledLabels as $enabledLabel) {
    echo "$enabledLabel\n";
}

输出:

ajob
bjob
cjob

答案 1 :(得分:0)

下面的XSLT可以为您提供所需内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <xsl:for-each select="//*[fields/enable=1]">      
      <xsl:value-of select="name(current())" />      
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

现场直播:http://www.xsltcake.com/slices/JYfpsX/3

您可以使用xpath检索一组节点,然后您可以在PHP中循环并在每次迭代中检索节点的名称。 PHP DOMNode类(http://php.net/manual/en/class.domnode.php)有一个名为'nodeName'的属性。

答案 2 :(得分:0)

$sxe = new SimpleXMLElement($xml);
$element = $sxe->xpath("//wrapper/groups//fields[enable=1]/../label");

foreach($element as $node)
{
  echo $node,"<br/>";
}