现在使用Saxon处理器进行XSLT转换已有一段时间。通常,我可以找到我的答案并建立自己想要的东西,但这一次...
我需要将其他XML文件中的数据添加到现有XML,必须插入的数据由base-xml中的节点定义。
基本XML:
<gang_job version="1.2"
gang_job_name="Layout"
gang_job_id="Automatic gang job"
gang_job_customer_id="-1"
gang_job_customer_name="unnamed">
<mso_quality_job usage="85" total_cost="1000"/>
<mso_plate width="530"
height="459"
<mso_quality_plate>
<volume_use result="85.45333054436504"
volume_low="0"
volume_high="2147483647"/>
<multiple1up result="23.52227020526318"
active="false"
delivery_low="0"
delivery_high="2147483647"/>
</mso_quality_plate>
<gang_part part_id="MGD9E97H5D"
part_object="Block 1"
</gang_part>
<gang_part part_name="Ganging / HF_ganging"
part_id="MG3BE3D10G"
part_object="Block 1"
</gang_part>
</mso_plate>
</gang_job>
插入的XML文件的名称与gang_job / mso_plate / gang_part / @ part_id相同,必须插入/ orderMetadata / items / item之后的节点。
XML:
<?xml version="1.0" encoding="UTF-8"?>
<orderMetadata>
<orderId>MGD9E97H5D</orderId>
<items>
<item>
<itemId>MGD9E97H5D</itemId>
<isTestItem>false</isTestItem>
<sku>SKU</sku>
<orderId>1337</orderId>
<quantity>500</quantity>
<name>name</name>
<description>Description</description>
<document>URL to document</document>
<productManufacturingData>
<Material>Material</Material>
<Format>Format</Format>
<Finishing>Finishing</Finishing>
</productManufacturingData>
<deliveryDetails>
<deliveryDetail>
<type>Standard</type>
<quantity>500</quantity>
<destinationAddress>
<city>Amsterdam</city>
</destinationAddress>
</deliveryDetail>
</deliveryDetails>
</item>
</items>
</orderMetadata>
我正在尝试,但没有结果:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="gang_job/mso_plate/gang_part">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:variable name="Path">/Volumes/Directory/SubDirectory</xsl:variable>
<xsl:variable name="Extension">.xml</xsl:variable>
<xsl:variable name="FullPath" select="string(concat($docRoot,@part_id,$Extension))"/>
<xsl:for-each select="document($FullPath)/orderMetadata/items/item">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在没有变量的情况下我直接尝试了它:
<xsl:for-each select="document('/Volumes/Directory/SubDirectory{@part_id}.xml')/orderMetadata/items/item">
您接近。在您的第一个片段中,变量$docRoot
与$Path
似乎有些混乱。无论哪种方式,请记住document()需要一个URI,而不是文件名。我期望像"file:///Volumes/Directory/SubDirectoryMGD9E97H5D.xml"
之类的东西(或者“ SubDirectory”之后是否还有另一个斜杠?
您打算让URI是绝对的还是相对的?
我将样式表更改为使用version =“ 3.0”而不是“ 1.0”,因为这样可以进行更严格的检查,因此可以提供更好的诊断。
在第二个示例(显示您的第一个示例)中,在字符串文字中使用花括号是一厢情愿的想法。您需要使用字符串串联来构造URI。在XSLT 3.0(带有expand-text="yes"
)中,可以使用
<xsl:variable name="uri" as="xs:string>file:///Volumes/Directory/SubDirectory{$part_id}.xml</xsl:variable>
当您正确使用URI后,使用
<xsl:copy-of select="doc($uri)"/>
应该包括所有要做的事情。