I have a xml. I want to have the element <Quantity>
move into <WarehouseLine>
<?xml version="1.0"?>
<Container xmlns:ti="http://www.to-increase.com/data/blocks">
<WarehouseHeader>
<No>RMA-21001</No>
<Description>RMA t.b.v. order_id #2</Description>
<Duedate>17/11/2021</Duedate>
<Quantity>1</Quantity>
<WarehouseLine>
<ItemNo>7890</ItemNo>
<Description>Radiant Tee-L-Purple</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
</WarehouseHeader>
<WarehouseHeader>
<No>RMA-21003</No>
<Description>RMA t.b.v. order_id #32</Description>
<Duedate>02/12/2021</Duedate>
<Quantity>1</Quantity>
<WarehouseLine>
<ItemNo>4560</ItemNo>
<Description>Strive Shoulder Pack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
<Quantity>1</Quantity>
<WarehouseLine>
<ItemNo>1234</ItemNo>
<Description>Driven Backpack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
</WarehouseHeader>
</Container>
I can do this with a foreach, but in my case the only first <Quantity>
will be copied to <WarehouseLine>
.
Code
$xml = simplexml_load_string($output);
$qty = $xml->WarehouseHeader->Quantity;
foreach ($xml->WarehouseHeader as $WarehouseHeader) {
$child = $WarehouseHeader->WarehouseLine->addChild("Quantity", $qty);
}
echo $xml->asXML();
output
<?xml version="1.0"?>
<Container xmlns:ti="http://www.to-increase.com/data/blocks">
<WarehouseHeader>
<No>RMA-21001</No>
<Description>RMA t.b.v. order_id #2</Description>
<Duedate>17/11/2021</Duedate>
<Quantity>1</Quantity>
<WarehouseLine>
<ItemNo>7890</ItemNo>
<Description>Radiant Tee-L-Purple</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity></WarehouseLine>
</WarehouseHeader>
<WarehouseHeader>
<No>RMA-21003</No>
<Description>RMA t.b.v. order_id #32</Description>
<Duedate>02/12/2021</Duedate>
<Quantity>1</Quantity>
<WarehouseLine>
<ItemNo>4560</ItemNo>
<Description>Strive Shoulder Pack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity></WarehouseLine>
<Quantity>1</Quantity> //next quantities
<WarehouseLine>
<ItemNo>1234</ItemNo>
<Description>Driven Backpack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
</WarehouseHeader>
</Container>
should be--- see <Quantity>1</Quantity> //next quantities
<?xml version="1.0"?>
<Container xmlns:ti="http://www.to-increase.com/data/blocks">
<WarehouseHeader>
<No>RMA-21001</No>
<Description>RMA t.b.v. order_id #2</Description>
<Duedate>17/11/2021</Duedate>
<WarehouseLine>
<ItemNo>7890</ItemNo>
<Description>Radiant Tee-L-Purple</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
</WarehouseHeader>
<WarehouseHeader>
<No>RMA-21003</No>
<Description>RMA t.b.v. order_id #32</Description>
<Duedate>02/12/2021</Duedate>
<WarehouseLine>
<ItemNo>4560</ItemNo>
<Description>Strive Shoulder Pack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
<WarehouseLine>
<ItemNo>1234</ItemNo>
<Description>Driven Backpack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
</WarehouseHeader>
</Container>
CodePudding user response:
Here is XSLT based solution.
Two XSLT templates are doing what is needed:
- Supress Quantity elements on the WarehouseHeader element level.
- Move Quantity elements into the WarehouseLine element level.
Input XML
<?xml version="1.0"?>
<Container xmlns:ti="http://www.to-increase.com/data/blocks">
<WarehouseHeader>
<No>RMA-21001</No>
<Description>RMA t.b.v. order_id #2</Description>
<Duedate>17/11/2021</Duedate>
<Quantity>1</Quantity>
<WarehouseLine>
<ItemNo>7890</ItemNo>
<Description>Radiant Tee-L-Purple</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
</WarehouseHeader>
<WarehouseHeader>
<No>RMA-21003</No>
<Description>RMA t.b.v. order_id #32</Description>
<Duedate>02/12/2021</Duedate>
<Quantity>1</Quantity>
<WarehouseLine>
<ItemNo>4560</ItemNo>
<Description>Strive Shoulder Pack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
<Quantity>8</Quantity>
<WarehouseLine>
<ItemNo>1234</ItemNo>
<Description>Driven Backpack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
</WarehouseLine>
</WarehouseHeader>
</Container>
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ti="http://www.to-increase.com/data/blocks">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--supress Quantity-->
<xsl:template match="WarehouseHeader/Quantity"/>
<!--bring Quantity from directly above-->
<xsl:template match="WarehouseLine">
<xsl:copy>
<xsl:copy-of select="*"/>
<xsl:copy-of select="preceding-sibling::Quantity[1]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output XML
<Container xmlns:ti="http://www.to-increase.com/data/blocks">
<WarehouseHeader>
<No>RMA-21001</No>
<Description>RMA t.b.v. order_id #2</Description>
<Duedate>17/11/2021</Duedate>
<WarehouseLine>
<ItemNo>7890</ItemNo>
<Description>Radiant Tee-L-Purple</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
</WarehouseHeader>
<WarehouseHeader>
<No>RMA-21003</No>
<Description>RMA t.b.v. order_id #32</Description>
<Duedate>02/12/2021</Duedate>
<WarehouseLine>
<ItemNo>4560</ItemNo>
<Description>Strive Shoulder Pack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>1</Quantity>
</WarehouseLine>
<WarehouseLine>
<ItemNo>1234</ItemNo>
<Description>Driven Backpack</Description>
<UnitofMeasureCode>PCS</UnitofMeasureCode>
<Quantity>8</Quantity>
</WarehouseLine>
</WarehouseHeader>
</Container>
CodePudding user response:
Another option is to do sort of a cut and paste (or rather - copy, paste, delete) using xpath and simplexml:
$xml = simplexml_load_string($output);
#copy the quantities
$qtys = $xml->xpath('//WarehouseHeader//Quantity');
foreach ($qtys as $qty) {
#locate the destination
$dest = $qty->xpath('.//following-sibling::WarehouseLine')[0];
#paste the quantity
$dest->addChild("Quantity", $qty);
#delete the original
unset($qty[0]);
};
echo $xml->asXML();