# 转 DELMIA Apriso XML 的步骤 直接生成符合 DELMIA Apriso 要求的 TransportPathOrders XML,跳过 XSLT 转换步骤。 简化方案:直接生成目标XML 目标Schema(直接使用) 创建文件 TransportPathOrder.xsd(这是唯一需要的Schema文件): xml 复制 您的程序直接生成XML的代码 C# 示例(如果您用C#) csharp 复制 using System; using System.Collections.Generic; using System.Xml.Linq; using System.IO; public class TransportPathGenerator { public class PathPoint { public string Id { get; set; } public string Name { get; set; } public string Type { get; set; } // StartPoint, WayPoint, EndPoint public int Index { get; set; } public double X { get; set; } public double Y { get; set; } public double Z { get; set; } } public class PathEdge { public string Type { get; set; } // straight, arc public double PhysicalLength { get; set; } public TrajectoryInfo Trajectory { get; set; } } public class TrajectoryInfo { public Point3D StartTangent { get; set; } public Point3D EndTangent { get; set; } public Point3D ArcCenter { get; set; } public double Radius { get; set; } public double DeflectionAngle { get; set; } } public class Point3D { public double X { get; set; } public double Y { get; set; } public double Z { get; set; } } public void GenerateXml( string orderId, string orderName, List points, List edges, string outputPath) { XNamespace ns = "http://www.dassaultsystemes.com/delmia/apriso"; // 构建Nodes var nodesElement = new XElement(ns + "Nodes"); foreach (var point in points) { nodesElement.Add(new XElement(ns + "Node", new XElement(ns + "NodeId", point.Id), new XElement(ns + "SequenceId", point.Index), new XElement(ns + "NodeName", point.Name), new XElement(ns + "NodeType", point.Type), new XElement(ns + "Position", new XElement(ns + "X", point.X), new XElement(ns + "Y", point.Y), new XElement(ns + "Z", point.Z) ), new XElement(ns + "Released", "true") )); } // 构建Edges(需要关联起点和终点ID) var edgesElement = new XElement(ns + "Edges"); for (int i = 0; i < edges.Count; i++) { var edge = edges[i]; var startNode = points[i]; var endNode = points[i + 1]; var edgeElement = new XElement(ns + "Edge", new XElement(ns + "EdgeId", $"edge_{i}"), new XElement(ns + "EdgeType", edge.Type), new XElement(ns + "SequenceId", i), new XElement(ns + "StartNodeId", startNode.Id), new XElement(ns + "EndNodeId", endNode.Id), new XElement(ns + "PhysicalLength", edge.PhysicalLength) ); // 如果是弧线,添加轨迹信息 if (edge.Type == "arc" && edge.Trajectory != null) { edgeElement.Add(new XElement(ns + "Trajectory", new XElement(ns + "StartTangent", new XElement(ns + "X", edge.Trajectory.StartTangent.X), new XElement(ns + "Y", edge.Trajectory.StartTangent.Y), new XElement(ns + "Z", edge.Trajectory.StartTangent.Z) ), new XElement(ns + "EndTangent", new XElement(ns + "X", edge.Trajectory.EndTangent.X), new XElement(ns + "Y", edge.Trajectory.EndTangent.Y), new XElement(ns + "Z", edge.Trajectory.EndTangent.Z) ), new XElement(ns + "ArcCenter", new XElement(ns + "X", edge.Trajectory.ArcCenter.X), new XElement(ns + "Y", edge.Trajectory.ArcCenter.Y), new XElement(ns + "Z", edge.Trajectory.ArcCenter.Z) ), new XElement(ns + "Radius", edge.Trajectory.Radius), new XElement(ns + "DeflectionAngle", edge.Trajectory.DeflectionAngle) )); } edgesElement.Add(edgeElement); } // 构建完整文档 var document = new XDocument( new XDeclaration("1.0", "utf-8", null), new XElement(ns + "TransportPathOrders", new XElement(ns + "PathOrder", new XElement(ns + "OrderId", orderId), new XElement(ns + "OrderName", orderName), new XElement(ns + "Description", "NavisworksTransport生成的路径"), new XElement(ns + "PathType", "Ground"), new XElement(ns + "TotalLength", CalculateTotalLength(edges)), new XElement(ns + "Timestamp", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")), new XElement(ns + "Generator", "NavisworksTransport"), new XElement(ns + "Version", "1.0"), nodesElement, edgesElement, new XElement(ns + "ObjectLimits", new XElement(ns + "MaxLength", "0"), new XElement(ns + "MaxWidth", "0"), new XElement(ns + "MaxHeight", "0"), new XElement(ns + "SafetyMargin", "0") ), new XElement(ns + "CoordinateSystem", "Global") ) ) ); document.Save(outputPath); } private double CalculateTotalLength(List edges) { double total = 0; foreach (var edge in edges) total += edge.PhysicalLength; return total; } } // 使用示例 class Program { static void Main() { var generator = new TransportPathGenerator(); var points = new List { new AGVPathGenerator.PathPoint { Id = "3ada559e-36b9-4537-b341-cfff765c8d43", Name = "起点", Type = "StartPoint", Index = 0, X = -152.614, Y = 0.517, Z = 14.833 }, new AGVPathGenerator.PathPoint { Id = "042229ba-0ce2-4f6c-af8f-57f840300e82", Name = "路径点1", Type = "WayPoint", Index = 1, X = -131.345, Y = -14.532, Z = 14.75 }, new AGVPathGenerator.PathPoint { Id = "69fa7321-3dc5-4ec5-9c1f-74e2a6d787a5", Name = "终点", Type = "EndPoint", Index = 2, X = -55.369, Y = -0.504, Z = 14.833 } }; var edges = new List { new AGVPathGenerator.PathEdge { Type = "straight", PhysicalLength = 22.595 }, new AGVPathGenerator.PathEdge { Type = "arc", PhysicalLength = 6.548, Trajectory = new AGVPathGenerator.TrajectoryInfo { StartTangent = new AGVPathGenerator.Point3D { X = -134.17, Y = -12.533, Z = 14.761 }, EndTangent = new AGVPathGenerator.Point3D { X = -127.943, Y = -13.903, Z = 14.754 }, ArcCenter = new AGVPathGenerator.Point3D { X = -129.432, Y = -5.837, Z = 14.799 }, Radius = 8.202, DeflectionAngle = 0.798 } }, new AGVPathGenerator.PathEdge { Type = "straight", PhysicalLength = 73.8 } }; generator.GenerateXml( "17838e6e-1112-4e62-a3ab-d7a3354d39d3", "人工_0219_203325", points, edges, "output.xml" ); } } Python 示例(如果您用Python) Python 复制 import xml.etree.ElementTree as ET from datetime import datetime from dataclasses import dataclass from typing import List, Optional @dataclass class Point3D: x: float y: float z: float @dataclass class TrajectoryInfo: start_tangent: Point3D end_tangent: Point3D arc_center: Point3D radius: float deflection_angle: float @dataclass class PathPoint: id: str name: str type: str # StartPoint, WayPoint, EndPoint index: int x: float y: float z: float @dataclass class PathEdge: edge_type: str # straight, arc physical_length: float trajectory: Optional[TrajectoryInfo] = None class TransportPathGenerator: def __init__(self): self.ns = "http://www.dassaultsystemes.com/delmia/apriso" ET.register_namespace('', self.ns) def generate_xml(self, order_id: str, order_name: str, points: List[PathPoint], edges: List[PathEdge], output_path: str): # 创建根元素 root = ET.Element(f"{{{self.ns}}}TransportPathOrders") # 创建PathOrder path_order = ET.SubElement(root, f"{{{self.ns}}}PathOrder") # 基础信息 ET.SubElement(path_order, f"{{{self.ns}}}OrderId").text = order_id ET.SubElement(path_order, f"{{{self.ns}}}OrderName").text = order_name ET.SubElement(path_order, f"{{{self.ns}}}Description").text = "NavisworksTransport生成的路径" ET.SubElement(path_order, f"{{{self.ns}}}PathType").text = "Ground" ET.SubElement(path_order, f"{{{self.ns}}}TotalLength").text = str(sum(e.physical_length for e in edges)) ET.SubElement(path_order, f"{{{self.ns}}}Timestamp").text = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") ET.SubElement(path_order, f"{{{self.ns}}}Generator").text = "NavisworksTransport" ET.SubElement(path_order, f"{{{self.ns}}}Version").text = "1.0" # 创建Nodes nodes = ET.SubElement(path_order, f"{{{self.ns}}}Nodes") for point in points: node = ET.SubElement(nodes, f"{{{self.ns}}}Node") ET.SubElement(node, f"{{{self.ns}}}NodeId").text = point.id ET.SubElement(node, f"{{{self.ns}}}SequenceId").text = str(point.index) ET.SubElement(node, f"{{{self.ns}}}NodeName").text = point.name ET.SubElement(node, f"{{{self.ns}}}NodeType").text = point.type position = ET.SubElement(node, f"{{{self.ns}}}Position") ET.SubElement(position, f"{{{self.ns}}}X").text = str(point.x) ET.SubElement(position, f"{{{self.ns}}}Y").text = str(point.y) ET.SubElement(position, f"{{{self.ns}}}Z").text = str(point.z) ET.SubElement(node, f"{{{self.ns}}}Released").text = "true" # 创建Edges edges_elem = ET.SubElement(path_order, f"{{{self.ns}}}Edges") for i, edge in enumerate(edges): edge_elem = ET.SubElement(edges_elem, f"{{{self.ns}}}Edge") ET.SubElement(edge_elem, f"{{{self.ns}}}EdgeId").text = f"edge_{i}" ET.SubElement(edge_elem, f"{{{self.ns}}}EdgeType").text = edge.edge_type ET.SubElement(edge_elem, f"{{{self.ns}}}SequenceId").text = str(i) ET.SubElement(edge_elem, f"{{{self.ns}}}StartNodeId").text = points[i].id ET.SubElement(edge_elem, f"{{{self.ns}}}EndNodeId").text = points[i+1].id ET.SubElement(edge_elem, f"{{{self.ns}}}PhysicalLength").text = str(edge.physical_length) # 如果是弧线,添加轨迹 if edge.edge_type == "arc" and edge.trajectory: traj = ET.SubElement(edge_elem, f"{{{self.ns}}}Trajectory") start_tan = ET.SubElement(traj, f"{{{self.ns}}}StartTangent") ET.SubElement(start_tan, f"{{{self.ns}}}X").text = str(edge.trajectory.start_tangent.x) ET.SubElement(start_tan, f"{{{self.ns}}}Y").text = str(edge.trajectory.start_tangent.y) ET.SubElement(start_tan, f"{{{self.ns}}}Z").text = str(edge.trajectory.start_tangent.z) end_tan = ET.SubElement(traj, f"{{{self.ns}}}EndTangent") ET.SubElement(end_tan, f"{{{self.ns}}}X").text = str(edge.trajectory.end_tangent.x) ET.SubElement(end_tan, f"{{{self.ns}}}Y").text = str(edge.trajectory.end_tangent.y) ET.SubElement(end_tan, f"{{{self.ns}}}Z").text = str(edge.trajectory.end_tangent.z) arc_center = ET.SubElement(traj, f"{{{self.ns}}}ArcCenter") ET.SubElement(arc_center, f"{{{self.ns}}}X").text = str(edge.trajectory.arc_center.x) ET.SubElement(arc_center, f"{{{self.ns}}}Y").text = str(edge.trajectory.arc_center.y) ET.SubElement(arc_center, f"{{{self.ns}}}Z").text = str(edge.trajectory.arc_center.z) ET.SubElement(traj, f"{{{self.ns}}}Radius").text = str(edge.trajectory.radius) ET.SubElement(traj, f"{{{self.ns}}}DeflectionAngle").text = str(edge.trajectory.deflection_angle) # 对象限制 limits = ET.SubElement(path_order, f"{{{self.ns}}}ObjectLimits") ET.SubElement(limits, f"{{{self.ns}}}MaxLength").text = "0" ET.SubElement(limits, f"{{{self.ns}}}MaxWidth").text = "0" ET.SubElement(limits, f"{{{self.ns}}}MaxHeight").text = "0" ET.SubElement(limits, f"{{{self.ns}}}SafetyMargin").text = "0" ET.SubElement(path_order, f"{{{self.ns}}}CoordinateSystem").text = "Global" # 保存文件 tree = ET.ElementTree(root) tree.write(output_path, encoding='utf-8', xml_declaration=True) print(f"XML已生成: {output_path}") # 使用示例 if __name__ == "__main__": generator = TransportPathGenerator() points = [ PathPoint("3ada559e-36b9-4537-b341-cfff765c8d43", "起点", "StartPoint", 0, -152.614, 0.517, 14.833), PathPoint("042229ba-0ce2-4f6c-af8f-57f840300e82", "路径点1", "WayPoint", 1, -131.345, -14.532, 14.75), PathPoint("69fa7321-3dc5-4ec5-9c1f-74e2a6d787a5", "终点", "EndPoint", 2, -55.369, -0.504, 14.833) ] edges = [ PathEdge("straight", 22.595), PathEdge("arc", 6.548, TrajectoryInfo( Point3D(-134.17, -12.533, 14.761), Point3D(-127.943, -13.903, 14.754), Point3D(-129.432, -5.837, 14.799), 8.202, 0.798 )), PathEdge("straight", 73.8) ] generator.generate_xml( "17838e6e-1112-4e62-a3ab-d7a3354d39d3", "人工_0219_203325", points, edges, "transport_path.xml" ) 生成的 XML 示例 xml 复制 17838e6e-1112-4e62-a3ab-d7a3354d39d3 人工_0219_203325 NavisworksTransport生成的路径 Ground 102.943 2026-03-09T16:30:45Z NavisworksTransport 1.0 3ada559e-36b9-4537-b341-cfff765c8d43 0 起点 StartPoint -152.614 0.517 14.833 true 042229ba-0ce2-4f6c-af8f-57f840300e82 1 路径点1 WayPoint -131.345 -14.532 14.75 true 69fa7321-3dc5-4ec5-9c1f-74e2a6d787a5 2 终点 EndPoint -55.369 -0.504 14.833 true edge_0 straight 0 3ada559e-36b9-4537-b341-cfff765c8d43 042229ba-0ce2-4f6c-af8f-57f840300e82 22.595 edge_1 arc 1 042229ba-0ce2-4f6c-af8f-57f840300e82 69fa7321-3dc5-4ec5-9c1f-74e2a6d787a5 6.548 -134.17 -12.533 14.761 -127.943 -13.903 14.754 -129.432 -5.837 14.799 8.202 0.798 edge_2 straight 2 69fa7321-3dc5-4ec5-9c1f-74e2a6d787a5 终点_D 73.8 0 0 0 0 Global DELMIA Apriso 配置(简化版) 既然您直接生成目标XML,配置也简化了: 1. 部署Schema 将 TransportPathOrder.xsd 复制到: plain 复制 SchemaRepository/XMLSchemas/FlexNet/TransportPathOrder.xsd 2. Routing Configuration(仅需路由,无需XSLT) xml 复制 注意:不需要 Mapping Configuration,因为您直接生成了 Apriso 内部格式! 3. 创建Job Action处理程序 在DELMIA Apriso中创建 ProcessTransportPathOrder 来处理导入的路径数据。 关键优势 ✅ 无需 XSLT 转换:直接生成目标格式,性能更好 ✅ 配置更简单:只需配置路由,无需映射 ✅ 数据完整性:保留所有原始信息(轨迹、切线等) ✅ 支持吊装路径:扩展了 LiftPoint/DescendPoint/HoverPoint 等节点类型 ✅ 符合 Schema:遵循 TransportPathOrders.xsd 规范 您需要: 1. 把上面的 C# 或 Python 代码集成到您的程序中(或直接使用插件的导出功能) 2. 部署 XSD 文件到 Apriso 3. 配置简单的路由规则 4. 开发 Job Action 处理程序 > 注:插件已内置 ExportToDelmiaAprisoXml() 方法,在导出对话框中选择 `.delmiaxml` 格式即可直接生成符合该 Schema 的 XML 文件。