草庐IT

php - XML 和 PHP 空白的诅咒

coder 2024-07-02 原文

我在使用 DOMDocument 和空格时遇到问题。目前我有两种类型的 XML 文件。大约一年前手动创建了一个文件,我将此文件称为 A。第二个文件 B 是使用 PHP DOMDocument 生成的。我一直在努力(未成功)使文件 A 中的空格与文件 B 匹配。

它是这样工作的……用户可以选择添加新的<Slide>。 XML 文件中的元素。添加新幻灯片后,用户可以选择添加新的 <Items>到 XML 文件作为 <Slide> 的子项元素。

当我添加 <Slide>元素到文件 B 它就像一个魅力。我什至可以添加一个新的 <Item>零问题的元素。但是,当我尝试访问新的 <Identifier> 时元素我刚刚使用下面的第二个 PHP 脚本添加到文件 B 中 $order != 'remove'我错过了一个节点并选择 <Information/>反而。

手动创建的文件 A 似乎有我生成的文件 B 中不存在的空白。我已经尝试过 preserveWhitespace 属性,但它没有帮助。

关于如何解决这个问题有什么建议吗?也欢迎建设性的批评,因为这是我第一次尝试动态 XML 操作。很抱歉,感谢您抽出宝贵的时间!!

文件 A - 手动创建 - 我正在尝试匹配此文件!

<?xml version="1.0" encoding="UTF-8"?>
<root>
<Areas>Head &amp; Neck</Areas>
<Area>Head &amp; Neck</Area>
<Type>Angiograph</Type>
<Slide>Ag-01a
    <Title>Catheter Angiography</Title>
    <Item1>
        <Identifier interestCoord=".51,.73" locator="point" labelBool="true" labelTxt="" leaderBool="true">Aortic Arch
        </Identifier>
        <Information/>
        <Question A="" B="" C="" D="" E="" Answer=""/>
    </Item1>

             .... More Items 

文件 B - 在用户添加之前 <Slide> .这部分是手动创建的。 模板 如果您愿意的话。在用户输入幻灯片名称后,使用下面的代码块生成新幻灯片。

<?xml version="1.0" encoding="UTF-8"?>
<root>
<Areas>Head &amp; Neck</Areas>
<Area>Head &amp; Neck</Area>
<Type>Brain Sections</Type>
</root>

文件 B - 在用户添加新的 <Slide> 之后和 <Item> .显示的格式表示由 DOMDocument 创建的格式。 我认为这是错误发生的地方!空格!!!

<Slide>Ag-09a
    <Title>Catheter Angiography</Title>
<Item1><Identifier locator="point" interestCoord="0.143,0.65" labelBool="true" labelTxt="" leaderBool="false">Orbit</Identifier><Information/><Question A="" B="" C="" D="" E="" Answer=""/></Item1></Slide>

用于添加新的 PHP 脚本 <Slide>元素到 XML

<?php
session_start();

//Constants
$SECTION_SEP = "========================================================================</br>";

//Variables used to construct file path
$area = trim($_POST['area']);
$slideType = trim($_POST['slideType']);

$rawSlides = trim($_POST['theseSlides']);
$newSlideList = explode(",", $rawSlides);

$fileLocation = "../XML/".$area."/".$slideType."/".$area.".XML";

$dom = new DOMDocument();
echo('New DOMDocument created!</br>');

$dom->load($fileLocation);
echo('XML file loaded!</br>');

/*$dom->preserveWhiteSpace = false;
echo('White space removed!</br>');*/

$dom->documentElement;
echo('DOM initialized!</br>');

if ($dom->getElementsByTagName('Slide')->length == 0){  //New file with no slides

foreach ($newSlideList as $slide){
    $newSlide = $dom->createElement('Slide', $slide);
    $newTitle = $dom->createElement('Title', 'Scan');

    //Add the title element to the Item
    $newSlide->appendChild($newTitle);

    $dom->childNodes->item(0)->appendChild($newSlide);
    echo($slide." has been added to the list!</br>");
 }

} else {
$locators = $dom->getElementsByTagName('Slide');

}

if($dom->save($fileLocation)){
echo("File saved successfully!!");

}else echo("There was a problem saving the file!");

用于添加/编辑/删除的 PHP 脚本 <Item><Identifier>节点取决于 $orders 的值== 警告!冗长:/

<?php
session_start();

//Constants
$SECTION_SEP = "========================================================================</br>";

//Variables used to construct file path
$area = trim($_POST['area']);
$slideType = trim($_POST['slideType']);

$fileLocation = "../XML/".$area."/".$slideType."/".$area.".XML";

//echo("File location:".$fileLocation);

//Current data (c_ for current)
$c_poi = "";
$c_type = "";
$c_lblBool = "";
$c_lblOverride = "";
$c_leaderBool = "";

//Determine if this visit is for new or old data
$orders = trim($_POST['orders']);

//Variables used to replace information in XML file loaded below (n_ for new)
$n_slideName = trim($_POST['slideName']); //slide name in view format ie Ag-01a
$n_identName = trim($_POST['ident']); //contains multiple information separated by comma ie 0,Aortic Arch
$n_type = trim($_POST['type']); //locator type
$n_poi = trim($_POST['poi']);
$n_lblBool = trim($_POST['lblBool']);
$n_lblOverride = trim($_POST['lblOverride']);

echo("Modified: ".date('c')."</br>");
$dom = new DOMDocument();
echo('New DOMDocument created!</br>');

$dom->load($fileLocation);
echo('XML file loaded!</br>');

/*$dom->preserveWhiteSpace = false;
echo('White space removed!</br>');*/

$dom->documentElement;
echo('DOM initialized!</br>');

$locators = $dom->getElementsByTagName('Slide');
echo($locators->length.' elements retrieved</br>');

$slideEntryFound = false;
$identEntryFound = false;
$identAttributesFound = false;
echo($SECTION_SEP);

//Locate the correct slide node
foreach ($locators as $locator){

//If there is a match, store the infomation
// rawSlide[x].childNode[0].nodeValue
if(strcmp(trim($locator->childNodes->item(0)->nodeValue),$n_slideName) == 0){

    $slideEntryFound = true;
    $slideChildren = $locator->childNodes;

    //Locate the correct identifier node
    foreach($slideChildren as $child){

        if( strcmp(trim($child->nodeValue), substr($n_identName,strpos($n_identName,",")+1)) == 0){
            $identEntryFound = true;
            if (strcmp($orders, "remove") == 0){//Removing an element


                echo("The identifier being removed is: ".trim($child->nodeValue."</br>"));
                echo("The node path is: ".($child->childNodes->item(1)->getNodePath())."</br>");
                echo($SECTION_SEP);

                $locator->removeChild($child);
                echo("Identifier successfully removed!</br>");
                echo($SECTION_SEP);
                break;

            } else {//Not removing anything - Adding or Editing

                echo("The identifier being modified is: ".trim($child->nodeValue."</br>"));
                echo("The node path is: ".($child->childNodes->item(1)->getNodePath())."</br>");
                echo($SECTION_SEP);

                if($child->childNodes->item(1)->hasAttributes()){

                    $identAttributesFound = true;

                    $c_poi = $child->childNodes->item(1)->getAttribute('interestCoord');
                     echo("--Current interestCoord: ".$c_poi."</br>");
                     echo("++New interestCoord: ".$n_poi."</br>");
                    if(strcmp($c_poi, $n_poi) != 0){
                       $child->childNodes->item(1)->setAttribute('interestCoord',$n_poi);
                    }

                    $c_type = $child->childNodes->item(1)->getAttribute('locator');
                     echo("--Current locator: ".$c_type."</br>");
                     echo("++New locator: ".$n_type."</br>");

                    $c_lblBool = $child->childNodes->item(1)->getAttribute('labelBool');
                     echo("--Current labelBool: ".$c_lblBool."</br>");
                     //echo("++New labelBool: ".$n_lblBool."</br>");

                    $c_lblOverride = $child->childNodes->item(1)->getAttribute('labelTxt');
                     echo("--Current labelOverride: ".$c_lblOverride."</br>");
                     echo("++New labelOverride: ".$n_lblOverride."</br>");

                    $c_leaderBool = $child->childNodes->item(1)->getAttribute('leaderBool');
                     echo("--Current leaderBool: ".$c_leaderBool."</br>");
                     //echo("++New leaderBool: ".$n_leaderBool."</br>");

                    if($n_lblOverride != ""){
                        echo("**A new label override was detected. The identifier will have the alias ".$n_lblOverride.".");
                    }
               break;
            } else echo("Fatal Error - Node does not contain attributes!</br>");

            if($identEntryFound == true && $identAttributesFound == false)
                echo("Error - Attribute entry not found!");
            break;
            }
        }

    }

    if($slideEntryFound == true && $identEntryFound == false && $orders != "remove"){

        echo("The identifier was not found... creating a new identifier!</br>");

     //Create a new Element

        $newElement = $dom->createElement("Item".((integer)(substr($n_identName,0,strpos($n_identName,",")))+1));

        echo("New element created!!</br>");

        //Create new Item children
        $newSubElem = $dom->createElement("Identifier", substr($n_identName,strpos($n_identName,",")+1));
        $newSubElem->setAttribute('locator',$n_type);
        $newSubElem ->setAttribute('interestCoord',$n_poi);
        $newSubElem->setAttribute('labelBool', $n_lblBool);
        $newSubElem->setAttribute('labelTxt', $n_lblOverride);
        //TODO link this next one to a variable instead of hard coding
        $newSubElem->setAttribute('leaderBool', "false");

        //Info Child
        $newInfoElem = $dom->createElement("Information");
        //Question Child
        $newQuestion = $dom->createElement("Question");
            $newQuestion->setAttribute('A', "");
            $newQuestion->setAttribute('B', "");
            $newQuestion->setAttribute('C', "");
            $newQuestion->setAttribute('D', "");
            $newQuestion->setAttribute('E', "");
            $newQuestion->setAttribute('Answer', "");

        //Add new children to main Item
        $newElement->appendChild($newSubElem);
        $newElement->appendChild($newInfoElem);
        $newElement->appendChild($newQuestion);

        $locator->appendChild($newElement);


        echo("New identifier added!!</br>");

    break;
    }
} else {

}
}
if($slideEntryFound == false)
echo("Error - Slide entry not found!");

if($dom->save($fileLocation)){
echo("File saved successfully!!");

echo('<div id="phpHandleBtns>"></br><form><button type="submit" id="continueEdit" formaction="../edit.php">Continue Editing</button>'.
    '</br><button type="submit" id="doneEdit" formaction="../main.php">Done Editing</button></form></div>');

}else echo("There was a problem saving the file!");

?>

最佳答案

我强烈建议您使用像这样的 XPath API http://php.net/manual/en/class.domxpath.php找到您感兴趣的节点。尝试直接使用 DOM API 只会让您心痛。

更具体地说,我认为您对 childNode() 的调用被空格绊倒了,但是如果您改为使用 childElement() (不确定它是否存在,但使用 XPath 很容易),它会忽略任何空格。

关于php - XML 和 PHP 空白的诅咒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14568135/

有关php - XML 和 PHP 空白的诅咒的更多相关文章

  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 - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  3. ruby 诅咒颜色 - 2

    如何使用Ruby的默认Curses库获取颜色?所以像这样:puts"\e[0m\e[30;47mtest\e[0m"效果很好。在浅灰色背景上呈现漂亮的黑色。但是这个:#!/usr/bin/envrubyrequire'curses'Curses.noecho#donotshowtypedkeysCurses.init_screenCurses.stdscr.keypad(true)#enablearrowkeys(forpageup/down)Curses.stdscr.nodelay=1Curses.clearCurses.setpos(0,0)Curses.addstr"Hello

  4. ruby-on-rails - 如何为空白字段编写 rspec? [Rails3.1] - 2

    我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona

  5. ruby-on-rails - 如何在 Rails 3 中禁用 XML 解析 - 2

    我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::

  6. ruby - 如何使用 Nokogiri::XML::Builder 生成动态标签? - 2

    我正在遍历数组中的一组标签名称,我想使用构建器打印每个标签名称,而不是求助于“我认为:builder=Nokogiri::XML::Builder.newdo|xml|fortagintagsxml.tag!tag,somevalendend会这样做,但它只是创建名称为“tag”的标签,并将标签变量作为元素的文本值。有人可以帮忙吗?这个看起来应该比较简单,我刚刚在搜索引擎上找不到答案。我可能没有以正确的方式提问。 最佳答案 尝试以下操作。如果我没记错的话,我添加了一个根节点,因为Nokogiri需要一个。builder=Nokogi

  7. ruby - 如何让 Nokogiri 解析并返回 XML 文档? - 2

    这是一些奇怪的例子:#!/usr/bin/rubyrequire'rubygems'require'open-uri'require'nokogiri'print"withoutread:",Nokogiri(open('http://weblog.rubyonrails.org/')).class,"\n"print"withread:",Nokogiri(open('http://weblog.rubyonrails.org/').read).class,"\n"运行此返回:withoutread:Nokogiri::XML::Documentwithread:Nokogiri::

  8. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  9. ruby - 模式加载时出现 Nokogiri::XML::Schema SyntaxError - 2

    我正在尝试加载SAML协议(protocol)架构(具体来说:https://www.oasis-open.org/committees/download.php/3407/oasis-sstc-saml-schema-protocol-1.1.xsd),但在执行此操作之后:schema=Nokogiri::XML::Schema(File.read('saml11_schema.xsd'))我得到这个输出:Nokogiri::XML::SyntaxErrorException:Element'{http://www.w3.org/2001/XMLSchema}element',att

  10. ruby - 返回空白页的最小 Capybara/Poltergeist 测试 - 2

    看来我正在回顾SO帖子中采取的步骤:Capybara,PoltergeistandPhantomjsandgivinganemptyresponseinbody.(如果你愿意,可以将其标记为重复,但我包含了一个最小的独立测试用例和版本号。)问题我做错了什么吗?我可以运行另一个可能有助于隔离问题的最小测试吗?文件:pgtest.rbrequire'rubygems'require'capybara'require'capybara/dsl'require'capybara/poltergeist'modulePGTestincludeCapybara::DSLextendselfdeft

随机推荐