从XML内容中使用PHP获取元素

huangapple go评论93阅读模式
英文:

Get elements from a XML content by PHP

问题

我正在尝试从这个XML内容中获取元素,但返回为空:

  1. <results>
  2. <error>
  3. <string>i</string>
  4. <description>Make I uppercase</description>
  5. <precontext></precontext>
  6. <suggestions>
  7. <option>I</option>
  8. </suggestions>
  9. <type>grammar</type>
  10. </error>
  11. </results>

这是提取语法类型元素的代码:

  1. $dom = new DOMDocument();
  2. $dom->loadXml($output);
  3. $params = $dom->getElementsByTagName('error'); // 查找部分
  4. $k=0;
  5. foreach ($params as $param) // 逐个处理每个部分
  6. {
  7. if($param->type == "grammar"){
  8. echo $param->description;
  9. }else{
  10. echo "other type";
  11. }
  12. }

问题是脚本返回为空。

英文:

I am trying to get elements from this XML content but returns empty:

  1. &lt;results&gt;
  2. &lt;error&gt;
  3. &lt;string&gt;i&lt;/string&gt;
  4. &lt;description&gt;Make I uppercase&lt;/description&gt;
  5. &lt;precontext&gt;&lt;/precontext&gt;
  6. &lt;suggestions&gt;
  7. &lt;option&gt;I&lt;/option&gt;
  8. &lt;/suggestions&gt;
  9. &lt;type&gt;grammar&lt;/type&gt;
  10. &lt;/error&gt;
  11. &lt;/results&gt;

And this is my code to extract element type of grammar :

  1. $dom = new DOMDocument();
  2. $dom-&gt;loadXml($output);
  3. $params = $dom-&gt;getElementsByTagName(&#39;error&#39;); // Find Sections
  4. $k=0;
  5. foreach ($params as $param) //go to each section 1 by 1
  6. {
  7. if($param-&gt;type == &quot;grammar&quot;){
  8. echo $param-&gt;description;
  9. }else{
  10. echo &quot;other type&quot;;
  11. }

Problem is the script returns empty.

答案1

得分: 1

你可以使用 simplexml_load_string()

  1. $output = '<results>
  2. <error>
  3. <string>i</string>
  4. <description>将I大写</description>
  5. <precontext></precontext>
  6. <suggestions>
  7. <option>I</option>
  8. </suggestions>
  9. <type>语法</type>
  10. </error>
  11. </results>';
  12. $xml = simplexml_load_string($output);
  13. foreach($xml->error as $item)
  14. {
  15. //echo (string)$item->type;
  16. if($item->type == "语法"){
  17. echo $item->description;
  18. }else{
  19. echo "其他类型";
  20. }
  21. }
英文:

you can use simplexml_load_string()

  1. $output = &#39;&lt;results&gt;
  2. &lt;error&gt;
  3. &lt;string&gt;i&lt;/string&gt;
  4. &lt;description&gt;Make I uppercase&lt;/description&gt;
  5. &lt;precontext&gt;&lt;/precontext&gt;
  6. &lt;suggestions&gt;
  7. &lt;option&gt;I&lt;/option&gt;
  8. &lt;/suggestions&gt;
  9. &lt;type&gt;grammar&lt;/type&gt;
  10. &lt;/error&gt;
  11. &lt;/results&gt;&#39;;
  12. $xml = simplexml_load_string($output);
  13. foreach($xml-&gt;error as $item)
  14. {
  15. //echo (string)$item-&gt;type;
  16. if($item-&gt;type == &quot;grammar&quot;){
  17. echo $item-&gt;description;
  18. }else{
  19. echo &quot;other type&quot;;
  20. }
  21. }

答案2

得分: 1

你显然没有配置PHP来报告错误,因为你的代码触发了以下错误:

注意:未定义属性:DOMElement::$type

你需要以与获取<error>相同的方式获取<type>,使用DOM方法,例如getElementsByTagName()。对于节点的值也是一样的:

  1. if ($param->getElementsByTagName('type')->length && $param->getElementsByTagName('type')[0]->nodeValue === 'grammar') {
  2. // 随时可以添加其他检查:
  3. echo $param->getElementsByTagName('description')[0]->nodeValue;
  4. } else {
  5. echo "其他类型";
  6. }

演示

英文:

You apparently haven't configured PHP to report errors because your code triggers:

> Notice: Undefined property: DOMElement::$type

You need to grab &lt;type&gt; the same way you grab &lt;error&gt;, using DOM methods like e.g. getElementsByTagName(). Same for node value:

  1. if ($param-&gt;getElementsByTagName(&#39;type&#39;)-&gt;length &amp;&amp; $param-&gt;getElementsByTagName(&#39;type&#39;)[0]-&gt;nodeValue === &#39;grammar&#39;) {
  2. // Feel free to add additional checks here:
  3. echo $param-&gt;getElementsByTagName(&#39;description&#39;)[0]-&gt;nodeValue;
  4. }else{
  5. echo &quot;other type&quot;;
  6. }

Demo

答案3

得分: 1

I think is this what you want.

  1. <?php
  2. $output = '<results>
  3. <error>
  4. <string>i</string>
  5. <description>Make I uppercase</description>
  6. <precontext></precontext>
  7. <suggestions>
  8. <option>I</option>
  9. </suggestions>
  10. <type>grammar</type>
  11. </error>
  12. </results>';
  13. $dom = new DOMDocument();
  14. $dom->loadXml($output);
  15. $params = $dom->getElementsByTagName('error'); // Find Sections
  16. $k = 0;
  17. foreach ($params as $param) //go to each section 1 by 1
  18. {
  19. $string = $param->getElementsByTagName("string")->item(0)->nodeValue;
  20. $description = $param->getElementsByTagName("description")->item(0)->nodeValue;
  21. $option = $param->getElementsByTagName("option")->item(0)->nodeValue;
  22. $type = $param->getElementsByTagName("type")->item(0)->nodeValue;
  23. echo $type;
  24. if ($type == "grammar") {
  25. echo $description;
  26. } else {
  27. echo "other type";
  28. }
  29. }
  30. ?>
英文:

I think is this what you want.

  1. &lt;?php
  2. $output = &#39;&lt;results&gt;
  3. &lt;error&gt;
  4. &lt;string&gt;i&lt;/string&gt;
  5. &lt;description&gt;Make I uppercase&lt;/description&gt;
  6. &lt;precontext&gt;&lt;/precontext&gt;
  7. &lt;suggestions&gt;
  8. &lt;option&gt;I&lt;/option&gt;
  9. &lt;/suggestions&gt;
  10. &lt;type&gt;grammar&lt;/type&gt;
  11. &lt;/error&gt;
  12. &lt;/results&gt;&#39;;
  13. $dom = new DOMDocument();
  14. $dom-&gt;loadXml($output);
  15. $params = $dom-&gt;getElementsByTagName(&#39;error&#39;); // Find Sections
  16. $k=0;
  17. foreach ($params as $param) //go to each section 1 by 1
  18. {
  19. $string = $param-&gt;getElementsByTagName( &quot;string&quot; )-&gt;item(0)-&gt;nodeValue;
  20. $description = $param-&gt;getElementsByTagName( &quot;description&quot; )-&gt;item(0)-&gt;nodeValue;
  21. $option = $param-&gt;getElementsByTagName( &quot;option&quot; )-&gt;item(0)-&gt;nodeValue;
  22. $type = $param-&gt;getElementsByTagName( &quot;type&quot; )-&gt;item(0)-&gt;nodeValue;
  23. echo $type;
  24. if($type == &quot;grammar&quot;){
  25. echo $description ;
  26. }else{
  27. echo &quot;other type&quot;;
  28. }
  29. }
  30. ?&gt;

答案4

得分: 1

你正在混合使用DOM和SimpleXML。这是可能的,但你需要使用simplexml_import_dom()将DOM元素节点转换为SimpleXML实例。

或者你可以使用XPath。getElementsByTagName()是一种低级DOM方法。使用XPath表达式可以更具体地访问,而且需要更少的代码。

  1. $document = new DOMDocument();
  2. $document->loadXML($xml);
  3. $xpath = new DOMXpath($document);
  4. foreach ($xpath->evaluate('//error') as $error) {
  5. var_dump(
  6. [
  7. 'type' => $xpath->evaluate('string(type)', $error),
  8. 'description' => $xpath->evaluate('string(description)', $error)
  9. ]
  10. );
  11. }

输出:

  1. array(2) {
  2. ["type"]=>
  3. string(7) "grammar"
  4. ["description"]=>
  5. string(16) "Make I uppercase"
  6. }

XPath表达式还允许使用条件,例如你可以使用//error[@type = "grammar"]来获取所有语法错误。

英文:

You're mixing DOM with SimpleXML. This is possible, but you would need to convert the DOM element node into a SimpleXML instance with simplexml_import_dom().

Or you use Xpath. getElementsByTagName() is a low level DOM method. Using Xpath expressions allows for more specific access with a lot less code.

  1. $document = new DOMDocument();
  2. $document-&gt;loadXML($xml);
  3. $xpath = new DOMXpath($document);
  4. foreach ($xpath-&gt;evaluate(&#39;//error&#39;) as $error) {
  5. var_dump(
  6. [
  7. &#39;type&#39; =&gt; $xpath-&gt;evaluate(&#39;string(type)&#39;, $error),
  8. &#39;description&#39; =&gt; $xpath-&gt;evaluate(&#39;string(description)&#39;, $error)
  9. ]
  10. );
  11. }

Output:

  1. array(2) {
  2. [&quot;type&quot;]=&gt;
  3. string(7) &quot;grammar&quot;
  4. [&quot;description&quot;]=&gt;
  5. string(16) &quot;Make I uppercase&quot;
  6. }

Xpath expressions allow for conditions as well, for example you could fetch all grammar errors using //error[@type = &quot;grammar&quot;].

huangapple
  • 本文由 发表于 2020年1月3日 15:16:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/59574595.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定