PHP - 获取XML属性的值

时间:2015-05-31 00:57:18

标签: php xml attributes

source.xml

<property>
    <name>a</name>
    <description>aaa</description>
    <example value="b" description="bbb">b1</example>
    <example value="c" description="ccc">c1</example>   
</property> 

的search.php

$xmlDoc=new DOMDocument();
$xmlDoc->load("source.xml");
$x=$xmlDoc->getElementsByTagName('property');    
$z=$x->item(0);
$c=$z->childNodes;
for ($j=4;$j<($cd->length);$j++) {
 echo ("<div>" . $c->item($j)->attributes()->description . "</div>");
 echo ("<div>" . $c->item($j)->childNodes["description"] . "</div>");
 echo ("<div>" . $c->item($j)["description"] . "</div>");
}

我想返回一个属性description。我已经尝试了很多,但没有正常工作。

3 个答案:

答案 0 :(得分:1)

那是因为你做错了。基本上你想要解析XML。有几种方法可以做到这一点,但这里有一个:

echo once you fully understand this message, press "Y" to continue, or press "E" to exit.
choice /c ey
if errorlevel 2 goto :welcome
if errorlevel 1 goto :canceled

rem User pressed Ctrl+C

:canceled
rem User pressed E.  Do cancel stuff.
goto :eof

:welcome
rem User pressed Y.  Do welcome stuff
echo Welcome!

如果您希望遍历所有示例节点/元素,可以使用if (file_exists('source.xml')){ $xml = simplexml_load_file('source.xml'); } else { echo "Unable to load XML file!"; exit; } //This will output: bbb echo $xml->example[0]['description']; //This will output: ccc echo $xml->example[1]['description']; 循环轻松完成此操作:

foreach()

答案 1 :(得分:0)

<?php

$xmlDoc=new DOMDocument();
$xmlDoc->load('source.xml');

$properties = $xmlDoc->getElementsByTagName('property');    
$first_property = $properties->item(0);
echo "$first_property->tagName\n";

$first_property_children = $first_property->childNodes;
echo $first_property_children->length;

/*
for ($j=4;$j<($cd->length);$j++) {
 echo ("<div>" . $c->item($j)->attributes()->description . "</div>");
 echo ("<div>" . $c->item($j)->childNodes["description"] . "</div>");
 echo ("<div>" . $c->item($j)["description"] . "</div>");
}
 */
?>

--output:--
property
9

9 ?? !! WTF?这是你的xml文件的真实含义:

<property>\n  #<==SEE THIS??
    <name>a</name>\n  #<==AND HERE??
    <description>aaa</description>\n
    <example value="b" description="bbb">b1</example>\n
    <example value="c" description="ccc">c1</example> \n  
</property> 

当您在文本文件中点击Return时,会在文件中输入一个不可见的换行符。 xml认为每个新行都包含在一个不可见的文本节点中。由于property标记内的5个换行符以及其他4个可见节点创建了5个文本节点,因此property标记中共有9个子节点。

在你的循环中,只能登陆可见元素,你可以从childNodes [1]开始(跳过第一个换行文本节点),然后跳过每个其他的childNode:

for ($j=1; $j<($property_children->length); $j += 2) {

    echo ("<div>" . $property_children->item($j)->nodeValue . "</div>\n");

    //echo ("<div>" . $first_property_children->item($j)->nodeValue . "</div>");
    //echo ("<div>" . $first_property_children->item($j)->childNodes["description"] . "</div>");
    //echo ("<div>" . $first_property_children->item($j)["description"] . "</div>");
}

?>

--output:--
<div>a</div>
<div>aaa</div>
<div>b1</div>
<div>c1</div>

它为您提供所有可见标签的文本。

您可以在childNodes数组中找出description标记的位置,而不是循环。以下是您的描述标记位于childNodes数组中的位置:

                    +- from the spaces at the start of the next line
                    |
             0      V           1            2                    3
<property><text>\n    </text><name>a</name><text>\n   </text><description>aaa</description>....

所以,你可以写:

echo $property_children->item(3)->nodeValue;  //nodeValue gives you the text 

--output:--
aaa

但是必须对节点进行计数并考虑由标签内的空格创建的不可见文本节点对于我们糟糕的程序员来说太麻烦了,所以还有其他方法可以获得子节点:

<?php

if ($property = simplexml_load_file('source.xml') ) 
{
    //Grab all the child description tags in an Array:
    echo $property->description[0] . "\n";

    //Doing the same thing with xpath(which treats xml like a directory structure on your computer):
    echo $property->xpath('./description')[0] . "\n";

}

?>


--output:--
aaa
aaa

请参阅php文档中的Basic SimpleXML usage

  

我想返回属性说明。

一个属性?你的意思是所有示例标签的描述属性?

您可以将标记视为数组,并使用属性名称作为下标:

<?php

if ($property = simplexml_load_file('source.xml') ) 
{

    $example_tags = $property->example;

    foreach($example_tags as $example_tag) {
        echo $example_tag['description'];
    }

}

?>
--output:--
bbb
ccc

这是xpath:

<?php

if ($property = simplexml_load_file('source.xml') ) 
{

    $description_attrs = $property->xpath('./example/@description');

    foreach($description_attrs as $description_attr) {
        echo "$description_attr\n";
    }


}

?>

--output:--
bbb
ccc

答案 2 :(得分:0)

XML文档中的任何内容都将导致DOM中的节点,元素,属性,命名空间定义,xml声明文本甚至空格。换行符和空格等空格存储为text nodes

您可以选择忽略空白节点:

$xmlDoc = new DOMDocument();
$xmlDoc->preserveWhiteSpace = FALSE;
$xmlDoc->load($xmlFile);
...

PHPs DOM扩展支持XPath。有了它,您可以使用表达式来获取节点和值。

$source = new DOMDocument();
$source->loadXml($xml);
$xpath = new DOMXPath($source);

$target = new DOMDocument();
$fragment = $target->createDocumentFragment();

foreach ($xpath->evaluate('//property') as $property) {
  $fragment
    ->appendChild($target->createElement('div'))
    ->appendChild(
      $target->createTextNode(
        $xpath->evaluate('string(name)', $property)
      )
    );
  $fragment
    ->appendChild($target->createElement('div'))
    ->appendChild(
      $target->createTextNode(
        $xpath->evaluate('string(description)', $property)
      )
    );
  foreach ($xpath->evaluate('example', $property) as $example) {
    $fragment
      ->appendChild($target->createElement('div'))
      ->appendChild(
        $target->createTextNode(
          $xpath->evaluate('string(@description)', $example)
        )
      );
  }
}

echo $target->saveHtml($fragment);

输出:

<div>a</div><div>aaa</div><div>bbb</div><div>ccc</div>

使用DOM生成HTML可以避免出现问题。

Bu XPath表达式更强大。例如,从文档中获取所有描述节点(属性和元素)可以使用单个表达式完成:

$source = new DOMDocument();
$source->loadXml($xml);
$xpath = new DOMXPath($source);

$target = new DOMDocument();
$fragment = $target->createDocumentFragment();

foreach ($xpath->evaluate('//property//description|//property//*/@description') as $node) {
  $fragment
    ->appendChild($target->createElement('div'))
    ->appendChild(
      $target->createTextNode(
        $xpath->evaluate('string(.)', $node)
      )
    );
}

echo $target->saveHtml($fragment);

输出:

<div>aaa</div><div>bbb</div><div>ccc</div>