我是XSLT的新手,我很难找到解决以下问题的方法。
我正在尝试从基于IPC-257x标准的XML文件输出项目的缩进物料清单(BOM)以及添加的序列ID。在源XML文件中,有一个<Item>
元素,使用属性/值isTopLevel="Yes"
定义。这个元素定义了整个BOM结构的顶级Item。 BOM结构的下一级是在此Item的<BillOfMaterial>
子元素下定义的。每个子元素本身可以有自己的BOM结构,该结构在其<Item>
祖先的兄弟之下定义。此外,这些子元素中的每一个都可能有自己的BOM结构,这些结构也是<Item>
祖先的兄弟。
我尝试过(没有成功)许多不同的解决方案,首先将多个<xsl:for-each>
语句嵌入到一起,然后才意识到这可能不是最佳实践。随后,我尝试定义多个<xsl:templates>
;然而,这是难以理解的地方,主要是对同一节点使用多个模板以及需要使用<xsl:param>
来定义过滤的想法。
我希望有人可以提供最佳实践建议或解决方案,而不是让自己更加困惑。我非常有信心递归迭代是必需的,但不知道如何到达那里。
提前感谢您的帮助!
XML Source(原版大得多的缩写版):
<ProductDataeXchangePackage>
<Items>
<Item isTopLevel="No" itemIdentifier="0115020040" description="STL, SH 14GA CR">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="8151400002" itemQuantity=".0001" proprietarySequenceIdentifier="0" />
</BillOfMaterial>
</Item>
<Item isTopLevel="No" itemIdentifier="3070001100" description="NUT, STD HEX M10-1.5 (SST)">
<Attachments>
<Attachment fileIdentifier="124559464" fileSize="52212"/>
<Attachment fileIdentifier="124559465" fileSize="411068"/>
<Attachment fileIdentifier="124559462" fileSize="32603"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="3070007006" description="WELDNUT, M6-1.0 (SST)"/>
<Item isTopLevel="No" itemIdentifier="3070028000" description="WELDNUT, M5 X 0.8 (SST)"/>
<Item isTopLevel="No" itemIdentifier="3070031000" description="WELDNUT, M12-1.75-6H (STEEL)"/>
<Item isTopLevel="No" itemIdentifier="3110011100" description="WASHER, FLAT M10 SST (DIN125)"/>
<Item isTopLevel="No" itemIdentifier="3110011120" description="WASHER, FLAT M12 SST (DIN125)"/>
<Item isTopLevel="No" itemIdentifier="3150021100" description="LOCKWASHER, SPLIT M10 SST (DIN127)"/>
<Item isTopLevel="No" itemIdentifier="3203271000" description="BOLT, CARRIAGE, M10-1.5 X 40MM"/>
<Item isTopLevel="No" itemIdentifier="8151400002" description="SPEC, SHIPPING">
<Attachments>
<Attachment fileIdentifier="118969381" fileSize="399829"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8172418068" description="SPEC,APPROVED ALT MATERIAL">
<Attachments>
<Attachment fileIdentifier="138337862" fileSize="145480"/>
<Attachment fileIdentifier="138337863" fileSize="38243"/>
<Attachment fileIdentifier="132421232" fileSize="35544"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8398222254" description="SKID, 36.75 X 57">
<Attachments>
<Attachment fileIdentifier="130404636" fileSize="49406"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8435567553" description="FAB INSTR., SIDE BRACE">
<Attachments>
<Attachment fileIdentifier="142071491" fileSize="102438"/>
<Attachment fileIdentifier="142071490" fileSize="887808"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8435567554" description="FAB INSTR., BASE">
<Attachments>
<Attachment fileIdentifier="172551083" fileSize="1881600"/>
<Attachment fileIdentifier="172573685" fileSize="145681"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8435567555" description="FAB INSTR., TOP">
<Attachments>
<Attachment fileIdentifier="171051100" fileSize="126563"/>
<Attachment fileIdentifier="171051099" fileSize="1575424"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8435602286" description="ASSY INST, RACK WELDMT, 37RU">
<Attachments>
<Attachment fileIdentifier="135543730" fileSize="155618"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8435602287" description="FAB INST., CORNER POST, LEFT FRONT">
<Attachments>
<Attachment fileIdentifier="129272424" fileSize="603648"/>
<Attachment fileIdentifier="132214666" fileSize="39296"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8435602288" description="FAB INST., CORNER POST, RIGHT REAR">
<Attachments>
<Attachment fileIdentifier="121115929" fileSize="549888"/>
<Attachment fileIdentifier="132214667" fileSize="37265"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8435602289" description="FAB INST., CORNER POST, RIGHT FRONT">
<Attachments>
<Attachment fileIdentifier="129285018" fileSize="604160"/>
<Attachment fileIdentifier="132214668" fileSize="38840"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="8435602290" description="FAB INST., CORNER POST, LEFT REAR">
<Attachments>
<Attachment fileIdentifier="132214669" fileSize="36957"/>
<Attachment fileIdentifier="130362337" fileSize="702464"/>
</Attachments>
</Item>
<Item isTopLevel="No" itemIdentifier="9435567553" description="BRACE, SIDE">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="8172418068" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8435567553" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="0115020040" itemQuantity="11.00" proprietarySequenceIdentifier="1"/>
</BillOfMaterial>
</Item>
<Item isTopLevel="No" itemIdentifier="9435567554" description="BASE, CABINET FRAME">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="8172418068" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8435567554" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="0115020040" itemQuantity="50.7" proprietarySequenceIdentifier="1"/>
</BillOfMaterial>
</Item>
<Item isTopLevel="No" itemIdentifier="9435567555" description="TOP, CABINET FRAME">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="8172418068" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8435567555" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="0115020040" itemQuantity="50.7" proprietarySequenceIdentifier="1"/>
</BillOfMaterial>
</Item>
<Item isTopLevel="Yes" itemIdentifier="9435602286" description="WELDMENT, 37RU RACK">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="3070001100" itemQuantity="2.000" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="3110011100" itemQuantity="2.000" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="3110011120" itemQuantity="2.000" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="3150021100" itemQuantity="2.000" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="3203271000" itemQuantity="2.000" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8398222254" itemQuantity="1.0000" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8435602286" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="9435567554" itemQuantity="1" proprietarySequenceIdentifier="1"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="9435567555" itemQuantity="1" proprietarySequenceIdentifier="2"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="9435602287" itemQuantity="1" proprietarySequenceIdentifier="3"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="9435602288" itemQuantity="1" proprietarySequenceIdentifier="4"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="9435602289" itemQuantity="1" proprietarySequenceIdentifier="5"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="9435602290" itemQuantity="1" proprietarySequenceIdentifier="6"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="9435567553" itemQuantity="4" proprietarySequenceIdentifier="8"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="3070031000" itemQuantity="8" proprietarySequenceIdentifier="9"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="3070007006" itemQuantity="8" proprietarySequenceIdentifier="10"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="3070028000" itemQuantity="2" proprietarySequenceIdentifier="11"/>
</BillOfMaterial>
</Item>
<Item isTopLevel="No" itemIdentifier="9435602287" description="CORNER POST, LEFT FRONT">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="8172418068" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8435602287" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="0115020040" itemQuantity="5.137" proprietarySequenceIdentifier="1"/>
</BillOfMaterial>
</Item>
<Item isTopLevel="No" itemIdentifier="9435602288" description="CORNER POST, RIGHT REAR">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="8172418068" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8435602288" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="0115020040" itemQuantity="5.137" proprietarySequenceIdentifier="1"/>
</BillOfMaterial>
</Item>
<Item isTopLevel="No" itemIdentifier="9435602289" description="CORNER POST, RIGHT FRONT">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="8172418068" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8435602289" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="0115020040" itemQuantity="5.137" proprietarySequenceIdentifier="1"/>
</BillOfMaterial>
</Item>
<Item isTopLevel="No" itemIdentifier="9435602290" description="CORNER POST, LEFT REAR">
<BillOfMaterial>
<BillOfMaterialItem billOfMaterialItemIdentifier="8172418068" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="8435602290" itemQuantity="0.0001" proprietarySequenceIdentifier="0"/>
<BillOfMaterialItem billOfMaterialItemIdentifier="0115020040" itemQuantity="5.137" proprietarySequenceIdentifier="1"/>
</BillOfMaterial>
</Item>
</Items>
</ProductDataeXchangePackage>
这是对XSL的一次(非常粗略的)尝试;只进入一个BOM级别深度:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="ProductDataeXchangePackage/Items/Item[@isTopLevel='Yes']/BillOfMaterial">
<xsl:for-each select="BillOfMaterialItem">
<xsl:value-of select="position()"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="@billOfMaterialItemIdentifier"/>
<xsl:text> </xsl:text>
<!--<xsl:apply-templates/>-->
</xsl:for-each>
</xsl:template>
<!--
<xsl:template name="test" match="item">
<xsl:value-of select="@itemIdentifier"/>
<xsl:for-each select="@itemIdentifier">
<xsl:value-of select="@*"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
-->
</xsl:stylesheet>
这是所需的输出:
0 9435602286
1 3070001100
2 3110011100
3 3110011120
4 3150021100
5 3203271000
6 8398222254
7 8435602286
8 9435567554
9 8172418068
10 8435567554
11 0115020040
12 8151400002
13 9435567555
14 8172418068
15 8435567555
16 0115020040
17 8151400002
18 9435602287
19 8172418068
20 8435602287
21 0115020040
22 8151400002
23 9435602288
24 8172418068
25 8435602288
26 0115020040
27 8151400002
28 9435602289
29 8172418068
30 8435602289
31 0115020040
32 8151400002
33 9435602290
34 8172418068
35 8435602290
36 0115020040
37 8151400002
38 9435567553
39 8172418068
40 8435567553
41 0115020040
42 8151400002
43 3070031000
44 3070007006
45 3070028000
答案 0 :(得分:1)
我不理解你输出的逻辑。我原本预计缩进会随着BOM层次结构的每个级别而增加 - 在给定的示例中看起来像这样:
9435602286
3070001100
3070007006
3070028000
3070031000
3110011100
3110011120
3150021100
3203271000
8398222254
8435602286
9435567553
0115020040
8151400002
8172418068
8435567553
9435567554
0115020040
8151400002
8172418068
8435567554
9435567555
0115020040
8151400002
8172418068
8435567555
9435602287
0115020040
8151400002
8172418068
8435602287
9435602288
0115020040
8151400002
8172418068
8435602288
9435602289
0115020040
8151400002
8172418068
8435602289
9435602290
0115020040
8151400002
8172418068
8435602290
使用 key 可以轻松生成以递归方式将每个项目链接到其组件:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:key name="bom" match="Item" use="@itemIdentifier" />
<xsl:template match="/ProductDataeXchangePackage">
<xsl:apply-templates select="Items/Item[@isTopLevel='Yes']"/>
</xsl:template>
<xsl:template match="Item">
<xsl:param name="indent"/>
<xsl:value-of select="$indent"/>
<xsl:value-of select="@itemIdentifier"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="key('bom', BillOfMaterial/BillOfMaterialItem/@billOfMaterialItemIdentifier)">
<xsl:with-param name="indent" select="concat($indent, '	')"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
然后如何通过proprietarySequenceIdentifier对输出进行排序 by itemIdentifier?
此请求的问题是proprietarySequenceIdentifier
不是Item
本身的属性;它是&#34;父母&#34;的BillOfMaterialItem
孙子的一个属性。 Item
。
我把'#34;父母&#34;在引号中,因为它在源XML结构中并不是它的父级(这就是原始问题的内容)。
要解决此问题,我们必须Item
&#34;回到&#34;并从相应的proprietarySequenceIdentifier
节点获取BillOfMaterialItem
值:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:key name="item" match="Item" use="@itemIdentifier" />
<xsl:key name="bom-item" match="BillOfMaterialItem" use="@billOfMaterialItemIdentifier" />
<xsl:template match="/ProductDataeXchangePackage">
<xsl:apply-templates select="Items/Item[@isTopLevel='Yes']">
<xsl:sort select="@itemIdentifier" data-type="number" order="ascending"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Item">
<xsl:param name="indent"/>
<xsl:value-of select="$indent"/>
<xsl:value-of select="@itemIdentifier"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="key('item', BillOfMaterial/BillOfMaterialItem/@billOfMaterialItemIdentifier)">
<xsl:with-param name="indent" select="concat($indent, '	')"/>
<xsl:sort select="key('bom-item', @itemIdentifier)/@proprietarySequenceIdentifier" data-type="number" order="ascending"/>
<xsl:sort select="@itemIdentifier" data-type="number" order="ascending"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>