草庐IT

PHP XML - 在特定位置插入 XML 节点

coder 2024-07-05 原文

我想在 XML 文件的特定位置插入一个带有子节点的节点。我该怎么做?

例如。如果我有这样的 XML:

<myvalues>
 <image name="img01">
    <src>test</src>
 </image>

 <image name="img02">
    <src>test</src>
 </image>

 <image name="img03">
    <src>test</src>
 </image>
</myvalues>

我要插入:

<image name="img11">
  <src>test2</src>
</image>

<image name="img01"> 之间& <image name="img02"> .我该怎么做呢?我现在正在使用 SimpleXML 来读取 XML。

谢谢。

编辑:我尝试了以下代码。但是,新节点被添加到 XML 结构之外的 XML 底部。

$xml = new DomDocument();


$xml->preserveWhitespace = false;
 $xml->load('myXMLFile.xml');

 $newNode = $xml->createElement('tryimage');

 $xpath = new DOMXpath($xml);
 $elements = $xpath->query('/myvalues/image[name="img01"]');

 $refNode = $elements->item(0);

 $xml->insertBefore($newNode, $refNode->nextSibling);


 header('Content-Type: text/plain');
 echo $xml->saveXML();

输出是这样的:

<xml....>
   <myvalues>
     <image name="01">
     </image>
     .
     .
     .
   </myvalues>
<tryimage />

最佳答案

好吧,我看不到使用 SimpleXML 的简单方法(毕竟它应该很简单)。

一种方法是将 myvalues 节点移动到 DOMDocument,在其中添加节点,然后将其替换为 dom 节点。鉴于 $myvalues是你的 <myvalues> SimpleXML 中的节点:

$domMyValues = dom_import_simplexml($myvalues);
$newNode = $domMyValues->ownerDocument->createElement('mynewelement');
//Apply attributes and whatever to $newNode

//find the node that you want to insert it before (from the $domMyValues class
$nodes = $domMyValues->getElementsByTagName('image');
$refNode = null;
foreach ($nodes as $node) {
    if ($node->getAttribute('name') == 'img02') {
        $refNode = $node;
    }
}
$domMyValues->insertBefore($newNode, $refNode);

请注意,无需转换回 SimpleXML,因为对 DOMElement 的任何更改都会自动应用到 SimpleXML 版本...如果找不到 $refNode,它会自动附加新的子项。 (因为它不存在等)...

编辑:添加 XPath

用这个替换 foreach block (功能等效,如果我得到正确的查询):

$xpath = new DOMXpath($domMyValues->ownerDocument);
$elements = $xpath->query('//image[@name="img02"]');
$refNode = $elements->item(0);

DOMNodeList::item()对于不存在的偏移量返回 null,我们甚至不需要检查其中是否有项目。

现在,您可能需要/想要将 xpath 查询调整得更具体/更不具体。这是一个 decent tutorial ...

编辑2

我忘了 xpath 需要 @字符告诉它检查一个属性。

这是我的工作代码(因为我不知道您的确切架构):

$x = '<?xml version="1.0" ?>
<myvalues>
        <images>
                <image name="01">Foo</image>
                <image name="02">Bar</image>
        </images>
</myvalues>';

$dom = new DomDocument();
$dom->loadXML($x);
$xpath = new DOMXpath($dom);

$elements = $xpath->query('//images/image[@name="01"]');
$elements = $xpath->query('//image[@name="01"]');
$elements = $xpath->query('/myvalues/images/image[@name="01"]');

关于PHP XML - 在特定位置插入 XML 节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3054643/

有关PHP XML - 在特定位置插入 XML 节点的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. Ruby - 如何在读取文件时跳过/忽略特定行? - 2

    在读取/解析文件(使用Ruby)时忽略某些行的最佳方法是什么?我正在尝试仅解析Cucumber.feature文件中的场景,并希望跳过不以Scenario/Given/When/Then/And/But开头的行。下面的代码有效,但它很荒谬,所以我正在寻找一个聪明的解决方案:)File.open(file).each_linedo|line|line.chomp!nextifline.empty?nextifline.include?"#"nextifline.include?"Feature"nextifline.include?"Inorder"nextifline.include?

  3. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  4. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  5. ruby - 如何在 Ruby 字符串中插入项目符号字符? - 2

    我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195

  6. ruby - 下载位置 Selenium-webdriver Cucumber Chrome - 2

    我将Cucumber与Ruby结合使用。通过Selenium-Webdriver在Chrome中运行测试时,我想将下载位置更改为测试文件夹而不是用户下载文件夹。我当前的chrome驱动程序是这样设置的:Capybara.default_driver=:seleniumCapybara.register_driver:seleniumdo|app|Capybara::Selenium::Driver.new(app,:browser=>:chrome,desired_capabilities:{'chromeOptions'=>{'args'=>%w{window-size=1920,1

  7. ruby - Heroku production.log 文件位置 - 2

    我想在heroku.com上查看我的应用程序日志的内容,所以我关注了thisexcellentadvice并拥有我所有的日志内容。但是我现在很想知道我的日志文件实际在哪里,因为“log/production.log”似乎是空的:C:\>herokuconsoleRubyconsoleforajpbrevx.heroku.com>>files=Dir.glob("*")=>["public","tmp","spec","Rakefile","doc","config.ru","app","config","lib","README","Gemfile.lock","vendor","sc

  8. ruby - 在 Ruby 中查找多个正则表达式匹配的模式和位置 - 2

    这应该是一个简单的问题,但我找不到任何相关信息。给定一个Ruby中的正则表达式,对于每个匹配项,我需要检索匹配的模式$1、$2,但我还需要匹配位置。我知道=~运算符为我提供了第一个匹配项的位置,而string.scan(/regex/)为我提供了所有匹配模式。如果可能,我需要在同一步骤中获得两个结果。 最佳答案 MatchDatastring.scan(regex)do$1#Patternatfirstposition$2#Patternatsecondposition$~.offset(1)#Startingandendingpo

  9. ruby - 在 ruby​​ 中使用自动创建插入数组 - 2

    我想知道是否可以通过自动创建数组来插入数组,如果数组不存在的话,就像在PHP中一样:$toto[]='titi';如果尚未定义$toto,它将创建数组并将“titi”压入。如果已经存在,它只会推送。在Ruby中我必须这样做:toto||=[]toto.push('titi')可以一行完成吗?因为如果我有一个循环,它会测试“||=”,除了第一次:Person.all.eachdo|person|toto||=[]#with1billionofperson,thislineisuseless999999999times...toto.push(person.name)你有更好的解决方案吗?

  10. ruby-on-rails - Ruby on Rails - 需要在每周的特定时间将消息发送到电子邮件 - 2

    我想知道我应该如何着手这个项目。我需要每周向人们发送一次电子邮件。但是,这必须在每周的特定时间自动生成并发送。编码有多难?我需要知道是否有任何书籍可以提供帮助,或者你们中的任何人是否可以指导我。它必须使用ruby​​onrails进行编程。因此有一个网络服务和数据库集成。干杯 最佳答案 为什么这么复杂?您只需安排工作。您可以使用Delayed::Job例如。Delayed::Job让您可以使用run_at符号在特定时间安排作业,如下所示:Delayed::Job.enqueue(SendEmailJob.new(...),:run_

随机推荐