从xml文档中获取一些值

时间:2015-04-13 21:53:54

标签: xml delphi

我有这个xml文件:

<?xml version="1.0" encoding="Windows-1252"?>
<PPSExport Version="1.1">
  <JobFeedback Jobname="JOBM3003">
    <TimeStamp>16.03.2015 10:10:33</TimeStamp>
    <WorkPlace>TruLaser 3030 (L3030)_1_Sin 840D_1</WorkPlace>
    <CostCenter />
    <Barcode>1200004469</Barcode>
    <ManufacturingOrders>
      <ManufacturingOrder ManufacturingOrderName="JOBM3003_1">
        <Barcode>1100167056</Barcode>
        <ProgramName>JOBM3003_1</ProgramName>
        <NoOfRuns>1</NoOfRuns>
        <ProcessingTime>28.6900</ProcessingTime>
        <Sheet SheetIdentNo="M01317">
          <RawMaterial>11373-60</RawMaterial>
          <Dimensions>
            <Length>3000.00000</Length>
            <Width>1500.00000</Width>
            <Thickness>6.00000000000000000</Thickness>
            <Unit>mm</Unit>
          </Dimensions>
          <SheetWeight>211.95000</SheetWeight>
        </Sheet>
        <MinimumSheetSizeInX>2993.50</MinimumSheetSizeInX>
        <MinimumSheetSizeInY>1495.01</MinimumSheetSizeInY>
        <Waste>32.39</Waste>
        <PartsOnSheet>
          <Part PartNo="108278A" OrderNo="114619-*-*">
            <Barcode>0300036390</Barcode>
            <OperationBarcode>0100078904</OperationBarcode>
            <PartNoExt>L108278</PartNoExt>
            <PartDescription>EQUERRE RENFORT LONGERON G</PartDescription>
            <DrawingNo>M01317</DrawingNo> ......

我需要获取PartNoExt的值并将其放入Memo.Lines

如果有多个值,我需要所有这些值。

我试过了:

procedure TForm1.Button1Click(Sender: TObject);
var
  DOC:IXMLDocument;
  i: Integer;
  OrderChilds, E1EDP01_Node: IXMLNode;
begin
  DOC := LoadXMLDocument('JobExp4030.XML');
  // iterate your root node 'OREDERS'
  for i := 0 to DOC.ChildNodes.Nodes['PPSExport'].ChildNodes.Count - 1 do
  begin
    OrderChilds := DOC.ChildNodes.Nodes['PPSExport'].ChildNodes[i];
    if OrderChilds.NodeName = 'PartsOnSheet' then  // Your node(s) of interest
    begin
      E1EDP01_Node := OrderChilds.ChildNodes.Nodes['Part'];
      if Assigned(E1EDP01_Node) then // did we find the node keeping the 'POSEX' node
        Memo1.Lines.Add(E1EDP01_Node.ChildNodes.Nodes['PartNoExt'].NodeValue)
    end;
  end;
end;

但它对我不起作用。

1 个答案:

答案 0 :(得分:1)

您没有考虑XML的完整节点层次结构。您的循环期望PartsOnSheet节点出现在层次结构的此位置:

/PPSExport/PartsOnSheet

但它确实位于此处:

/PPSExport/JobFeedback/ManufacturingOrders/ManufacturingOrder/PartsOnSheet

您需要向下钻取层次结构的每一层,因此请使用更像这样的内容:

procedure TForm1.Button1Click(Sender: TObject);
var
  Doc: IXMLDocument;
  i, j, k: Integer;
  Node, OrdersNode, PartsNode: IXMLNode;
begin
  Doc := LoadXMLDocument('JobExp4030.XML');
  for i := 0 to Doc.DocumentElement.ChildNodes.Count - 1 do
  begin
    Node := Doc.DocumentElement.ChildNodes[i];
    if Node.NodeName <> 'JobFeedback' then Continue;
    OrdersNode := Node.ChildNodes.Nodes['ManufacturingOrders'];
    for j := 0 to OrdersNode.ChildNodes.Count - 1 do
    begin
      Node := OrdersNode.ChildNodes[j];
      if Node.NodeName <> 'ManufacturingOrder' then Continue;
      PartsNode := Node.ChildNodes.Nodes['PartsOnSheet'];
      for k := 0 to PartsNode.ChildNodes.Count - 1 do
      begin
        Node := PartsNode.ChildNodes[k];
        if Node.NodeName <> 'Part' then Continue;
        Memo1.Lines.Add(Node.ChildNodes.Nodes['PartNoExt'].NodeValue);
      end;
    end;
  end;
end;

如果您使用支持XPathDOMVendor(MSXML,ADOM,OmniXML等),则可以通过使用更类似的内容来大大简化代码:

procedure TForm1.Button1Click(Sender: TObject);
var
  Doc: IXMLDocument;
  i: Integer;
  XPathSelect: IDOMNodeSelect;
  List: IDOMNodeList;
  // variables for manual loop...
begin
  Doc := LoadXMLDocument('JobExp4030.XML');
  if Supports(Doc.DocumentElement, IDOMNodeSelect, XPathSelect) then
  begin
    List := XPathSelect.selectNodes('//PartNoExt');
    {if you need finer-grain control of where PartNoExt is found:
    List := XPathSelect.selectNodes('/PPSExport/JobFeedback/ManufacturingOrders/ManufacturingOrder/PartsOnSheet/Part/PartNoExt');}
    if List <> nil then
    begin
      for i := 0 to List.length - 1 do
        Memo1.Lines.Add(List.items[i].nodeValue);
    end;
  end else
  begin
    // the manual loop code shown above ...
  end;
end;