skip to Main Content

I’m trying to remove the parentnode itself from existing xml file

XMLfile1.xml

<?xml version="1.0"?>
<rss>
  <channel>
    <title>Main Website</title>
    <link>siteurl</link>
    <item>
      <item_type>Product</item_type>
      <title>abcd</title>
      <sku>TESTsku</sku>
      <id>919031</id>
      <short_description><![CDATA[]]></short_description>
      <description><![CDATA[]]></description>
      <link>siteurl</link>
      <availability>Out of Stock</availability>
      <price>21.81 CAD</price>
      <sale_price>21.81 CAD</sale_price>
      <categories>
        <category/>
      </categories>
      <attributes>
   </item>
  </channel>
</rss>

Expected XMLfile1.xml

<?xml version="1.0"?>
    <rss>
      <channel>
        <title>Main Website</title>
        <link>siteurl</link>
      </channel>
    </rss>

I want to remove the item node if the file exists.

What I have tried,

$xmlBase = <<<XML
<?xml version="1.0"?>
<rss>
<channel>
        <title>Main Website</title>
        <link>siteurl</link>
</channel>
</rss>
XML;

$status = 1;
if ($status == 1) {
    $entitiesXML = new SimpleXMLElement('XMLfile1.xml');
} else {
    $entitiesXML = new SimpleXMLElement($xmlBase);
}
$fileExist = 'XMLfile1.xml';
if (file_exists($fileExist)) {
    $doc1 = new DOMDocument('1.0');
    $doc1->loadXML($entitiesXML->asXML());
    $elements = $doc1->getElementsByTagName('channel');
    // $root = $doc1->firstChild;
    $nodes_to_insert = array();
    $nodes_to_remove = array();
    foreach($elements->childNodes as $item) {
        if($item->nodeName != "item") {
            continue;
        }
        $nodes_to_remove[] = $item;
    }
    foreach($nodes_to_remove as $node) {
        $elements->removeChild($node);
    }
    $doc1->saveXML();
}

I have tried bunch of other solutions with DOMXpath but not removing the item element.

2

Answers


  1. Chosen as BEST ANSWER

    Just realized that Instead of removing the parent node I can set it as $entitiesXML = new SimpleXMLElement($xmlBase);

    which will set the XML file as the result I wanted.

    <?xml version="1.0"?>
        <rss>
          <channel>
            <title>Main Website</title>
            <link>siteurl</link>
          </channel>
        </rss>
    

    My changes

    $xmlBase = <<<XML
    <?xml version="1.0"?>
    <rss>
    <channel>
            <title>Main Website</title>
            <link>siteurl</link>
    </channel>
    </rss>
    XML;
    
    $status = 1;
    if ($status == 1) {
        $entitiesXML = new SimpleXMLElement($xmlBase);
    } else {
        $entitiesXML = new SimpleXMLElement($xmlBase);
    }
    if (file_exists($fileExist)) {
        $dom = new DOMDocument('1.0');
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = true;
        $dom->loadXML($entitiesXML->asXML(), LIBXML_PARSEHUGE);
        $dom->saveXML();
    }
    

  2. Here is XSLT based solution.

    It is using a so called Identity Transform pattern.

    XSLT in PHP

    Input XML

    <?xml version="1.0"?>
    <rss>
        <channel>
            <title>Main Website</title>
            <link>siteurl</link>
            <item>
                <item_type>Product</item_type>
                <title>abcd</title>
                <sku>T-B-B220-TB</sku>
                <id>919031</id>
                <short_description><![CDATA[]]></short_description>
                <description><![CDATA[]]></description>
                <link>siteurl</link>
                <availability>Out of Stock</availability>
                <price>21.81 CAD</price>
                <sale_price>21.81 CAD</sale_price>
                <categories>
                    <category/>
                </categories>
                <attributes/>
            </item>
        </channel>
    </rss>
    

    XSLT

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <!--Identity Transform pattern-->
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <!--remove item element-->
        <xsl:template match="item"/>
    </xsl:stylesheet>
    

    Output XML

    <?xml version='1.0' ?>
    <rss>
      <channel>
        <title>Main Website</title>
        <link>siteurl</link>
      </channel>
    </rss>
    

    PHP

    $proc = new XSLTProcessor();
    $proc->importStylesheet($xsl);
    $newXml = $proc->transformToXML($xml);
    echo $newXml;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search