【问题标题】:simplexml get node value without typecastingsimplexml 在不进行类型转换的情况下获取节点值
【发布时间】:2011-01-18 09:54:25
【问题描述】:

有没有什么方法可以从simplexml 对象中获取节点值而不 转换它?

$amount = (int)$item->amount;

在我看来这不是很漂亮,我正在寻找一种更清洁的方式但到目前为止没有找到任何东西!

//wouldn't this be nice?
$amount = $item->amount->getValue();

提前致谢。

【问题讨论】:

  • PHP 有这个内置。不喜欢 type-casting 似乎是这里的问题,而不是 SimpleXML。但是,如果您坚持并更喜欢调用函数,那么您可能会感到惊讶;)有可用的转换函数。在您的情况下,它是intval(),还有strval()

标签: php casting simplexml


【解决方案1】:

没有。 SimpleXml 只公开了一个非常有限的 API 来处理节点。它的隐式 API 被认为是一项功能。如果您需要对节点进行更多控制,请使用DOM

$sxe = simplexml_load_string(
    '<root><item><amount>10</amount></item></root>'
);
$node = dom_import_simplexml($sxe->item->amount);
var_dump($node->nodeValue); // string(2) "10"

dom_import_simplexml 函数会将节点从SimpleXmlElement 转换为DOMElement,因此您仍然以某种方式在幕后进行转换。不过,从DOMElement 获取内容时,您不再需要显式类型转换。

附注:就个人而言,我发现DOM 优于SimpleXml,我建议不要使用SimpleXml,而是立即使用DOM。如果您想熟悉它,请查看some of my previous answers about using DOM

【讨论】:

  • 您建议使用更复杂的方式来处理 XML,原因不明。 OP 正在寻找“更清洁”的解决方案,DOM 比 SimpleXML 更加冗长,我怀疑它是否符合该描述。
  • @Josh 我认为有一个 API 可以明确地传达它所做的事情,这比 SimpleXml 提供的隐式接口要干净得多。是的,DOM 很冗长,但也更能处理各种节点类型(SimpleXml 对此一无所知)。此外,DOM 是一种与语言无关的接口规范,因此通过特定语言的扩展来学习它是值得的。
  • 我的意思是您不知道 Alex 是否需要任何 DOM 功能,因此您出于未知原因盲目地建议使用 DOM。我什至不知道您为什么要提出这些节点类型。我怀疑 Alex 正在寻找的值是否隐藏在 PI 中。为了公平对待不了解/不需要 DOM 的用户,您如何添加一个加载该 XML 并使用 DOM 将该值作为数字或字符串检索的示例?
  • @Josh 即使 Alex 不需要 DOM 目前提供的 ¾ 功能,使用高级包也没有缺点。 SimpleXml 仅适用于简单的 XML 用例。 DOM 适用于任何 XML(甚至是损坏的 HTML)。使用 DOM 也不是火箭科学。它易于使用,并具有清晰简洁的 API。仅凭这一点就足以在 SimpleXml 上考虑它。举个例子:不,我不会添加。我建议立即使用 DOM 是我回答的一个旁注。添加一个示例会过分强调这一点。无论如何,这些都是关于 SO for DOM 的大量示例。
  • 我的意思是你不知道 Alex 的需求。你不知道他是否需要处理 DOM 操作。也许他只是从外部源读取数据,而他所需要的只是干净、简单的方法。学习 DOM 从 XML 文件加载数据类似于学习 Javascript 从 JSON 文件加载数据。我注意到您还没有演示如何使用 DOM 读取该值。
【解决方案2】:

无需类型转换即可获取节点的值?确定的事! :3

class SimplerXMLElement extends SimpleXMLElement
{
    public function getValue()
    {
        return (string) $this;
    }
}

现在你只需要使用simplexml_load_string()的第二个参数来获得更更简单的XML元素!

更严重的是,一个节点就是一个节点。如果您需要将节点的值用作字符串、整数等,无论您是否亲自操作,都会在某一点或另一点涉及类型转换。

【讨论】:

  • 你在作弊。该值仍然是类型转换的。这是一个公平的解决方案,但具有讽刺意味的是,您对我的问题抱怨 cmets 中 DOM 的冗长,然后建议扩展 SimpleXml 以便能够提供 DOM 开箱即用的功能。如果您要针对 SimpleXml API 中的所有缺点这样做,那么您只是在重新发明 DOM。
  • 你没有抓住重点。这个类是一个开玩笑的例子,不管你是否意识到,类型转换总是会发生在某个地方。很抱歉你没听懂。
  • @Josh 我宁愿觉得我以某种方式侮辱了您的宠物 XML 扩展。还是你有什么其他理由贬低我?事实是,OP 没有询问 PHP 是否在后台进行任何类型转换,而是询问是否可以从 SimpleXmlElement 获取节点值而无需在脚本中明确转换。对此,答案是否定的,除非您喜欢“它是在实例中投射的,而不是脚本中的”那种狡辩。我当然不会。就像我说的,您的解决方案是公平的,但我仍然认为在 DOM 可用时向 SimpleXml 添加方法是浪费时间。随意不同意。
  • 你的“印象”是错误的。很抱歉,您要亲自参加有关编程的 cmets。我必须重申,我的课堂示例是“开玩笑的”,也就是说,我并不是认真地建议盲目地扩展 PHP 扩展。也许对某些人来说,为了避免类型转换而这样做是有意义的,但我的观点是,类型转换总是会发生,无论是在用户空间还是在 PHP 中。
  • @Josh 你一直在冒犯。请接受我不希望在此级别上继续讨论。
【解决方案3】:

但这是最安全的:)。您可以创建一个函数来递归地转换数组中的对象。当我第一次开始在 PHP 中使用 XML 时,我记得我得出的结论是类型转换只是最好的方法 :)

【讨论】:

    【解决方案4】:

    xpath 方式呢?

    $amount = $item->amount->xpath('text()');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      • 1970-01-01
      • 2019-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多