【问题标题】:move element into different element将元素移动到不同的元素中
【发布时间】:2022-01-12 13:56:49
【问题描述】:

我有一个 xml。我想让元素<Quantity> 移动到<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>

我可以使用 foreach 来做到这一点,但在我的情况下,唯一的第一个 &lt;Quantity&gt; 将被复制到 &lt;WarehouseLine&gt;

代码

$xml = simplexml_load_string($output);
$qty = $xml->WarehouseHeader->Quantity;
foreach ($xml->WarehouseHeader as $WarehouseHeader) {
    $child = $WarehouseHeader->WarehouseLine->addChild("Quantity", $qty);
}

echo $xml->asXML();

输出

<?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>

应该是---见&lt;Quantity&gt;1&lt;/Quantity&gt; //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>

【问题讨论】:

  • 此类任务最好使用 XSLT。

标签: php xml simplexml addchild


【解决方案1】:

另一种选择是使用 xpath 和 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();

【讨论】:

  • 太好了,这就是我想要的。谢谢 。现在我必须使 XML 可读 ;)
【解决方案2】:

这是基于 XSLT 的解决方案。

两个 XSLT 模板正在做需要做的事情:

  1. 抑制 WarehouseHeader 元素上的 Quantity 元素 水平。
  2. Quantity 元素移动到 WarehouseLine 元素中 水平。

输入 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>

输出 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>

【讨论】:

  • 这就是我想要的,很好。但是目前 xlst 对我来说不是一个选择
猜你喜欢
  • 2014-12-17
  • 1970-01-01
  • 2021-11-29
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多