2015-06-12 33 views
0

我有一個XSL文件,用於從多個源轉換/構建XML文件,其中多個元素和屬性需要隨時更新。我想知道這種情況是否應該在帶參數的<call-template/>塊中起作用。XSL - 使用具有多個源XML文件的調用模板

當我通過作爲參數傳遞的外部文件參考,EXPORT/Top/Shapes/Shape/Material下的「代碼」屬性不被更新:

<xsl:template match="Shapes"> 
    <xsl:copy> 
     <xsl:for-each select="document('..\TempReportData\TextXML_Output.xml')/Job/Benchtops/Benchtop"> 
      <xsl:apply-templates select="document('..\DesignMaster\EmptyShapeElement.xml')" /> 
      <xsl:call-template name="updateMaterial"> 
       <xsl:with-param name="mCode" select="./Top_number"/> 
      </xsl:call-template> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

<xsl:template name="updateMaterial" match="@Code[parent::Material]"> 
<xsl:param name="mCode"/> 
<xsl:attribute name="Code"> 
    <xsl:value-of select="$mCode"> 
</xsl:attribute> 
</xsl:template> 

這是期望的結果,其中<Material></Material>元件內的代碼屬性從更新外部文件:

<?xml version="1.0"?> 
<EXPORT> 
<Top Id="1" Code="B90512"> 
<Shapes> 
<!--Shape--> 
<Shape Id="1" Code="Penisola"> 
<!--Material--> 
<Material Code="TOP(2257)"></Material> 
</Shape> 
<!--Shape--> 
<Shape Id="1" Code="Penisola"> 
<!--Material--> 
<Material Code="TOP(2260)"></Material> 
</Shape> 
</Shapes> 
</Top> 
</EXPORT> 

XML文件TextXML_Output.xml是:

<?xml version="1.0"?> 
<Job> 
<Job_Number>B90512</Job_Number> 
<Job_Address>2nd Floor/ 28-32 Albert Road VIC 3205</Job_Address> 
<Benchtops> 
<Benchtop> 
<Top_number>TOP(2257)</Top_number> 
</Benchtop> 
<Benchtop> 
<Top_number>TOP(2260)</Top_number> 
</Benchtop> 
</Benchtops> 
</Job> 

使用多個模板和文件時,我感到有點迷茫,但在我看來,這應該可以正常工作,但事實並非如此。

+1

哪裏元素'Top_number'?它在'TextXML_Output.xml'中,還是在'EmptyShapeElement.xml'中? –

+0

'Top_number'位於'TextXML_Output.xml'中 – paularmy42

+0

考慮將所有需要的文檔儘可能減少到最小程度,以便讓我們重現它,然後發佈所有這些文檔。我們無法調試您不顯示的代碼,我們需要查看輸入文檔。 –

回答

1

沒有您Shapes匹配模板

<xsl:template match="Shapes"> 
    <xsl:copy> 
     <xsl:for-each select="document('..\TempReportData\TextXML_Output.xml')/Job/Benchtops/Benchtop"> 
      <xsl:apply-templates select="document('..\DesignMaster\EmptyShapeElement.xml')" /> 
      <xsl:call-template name="updateMaterial"> 
       <xsl:with-param name="mCode" select="./Top_number"/> 
      </xsl:call-template> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

通過創建在輸出Shapes元素開始一個問題。然後,您遍歷另一個文檔中的所有Benchtop元素,併爲每個元素複製一個「Empty Shape Xml」作爲您創建的Shapes元素的子元素。但是,您可以調用updateMaterial模板,該模板添加了一個屬性。這實際上將嘗試創建之前創建的父Shapes元素的屬性,而是根據W3C Specification ...

添加屬性給孩子已被添加到 後的元素它;實現可能會發出錯誤信號或忽略 屬性。

因此,在你的情況下,它看起來像XSLT處理器忽略了屬性,而不是拋出錯誤。

但是看着你想要達到的目標,它看起來像你想要添加屬性到Material元素,它是你正在複製的「EmptyShapeElement.xml」的一部分。

你可以做的是改變你的身份模板,我假設你的全XSLT使用,隨身攜帶一個mCode參數....

<xsl:template match="@*|node()"> 
    <xsl:param name="mCode"/> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"> 
      <xsl:with-param name="mCode" select="$mCode" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

然後Top_Number值傳遞的這個參數,當你選擇「EmptyShapeElement.xml」

<xsl:apply-templates select="$EmptyShapeElement"> 
    <xsl:with-param name="mCode" select="Top_number" /> 
</xsl:apply-templates> 

最後,對於屬性您現有的模板並不需要現在被命名爲

<xsl:template match="Material/@Code"> 
    <xsl:param name="mCode"/> 
    <xsl:attribute name="Code"> 
     <xsl:value-of select="$mCode" /> 
    </xsl:attribute> 
</xsl:template> 

(這是假設您要替換的「EmptyShapeElement.xml does indeed have an existing代碼」屬性中的Material元素。

試試這個XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

    <xsl:variable name="TextXML_Output" select="document('..\TempReportData\TextXML_Output.xml')" /> 
    <xsl:variable name="EmptyShapeElement" select="document('..\DesignMaster\EmptyShapeElement.xml')" /> 

    <xsl:template match="@*|node()"> 
     <xsl:param name="mCode"/> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"> 
       <xsl:with-param name="mCode" select="$mCode" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Shapes"> 
     <xsl:copy> 
      <xsl:for-each select="$TextXML_Output/Job/Benchtops/Benchtop"> 
       <xsl:apply-templates select="$EmptyShapeElement"> 
        <xsl:with-param name="mCode" select="Top_number" /> 
       </xsl:apply-templates> 
      </xsl:for-each> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Material/@Code"> 
     <xsl:param name="mCode"/> 
     <xsl:attribute name="Code"> 
      <xsl:value-of select="$mCode" /> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 
+0

感謝您的答案Tim C.這段代碼當然更清潔,但是當我運行它時,Code屬性仍然沒有正確更新。它保存爲'Code =「」'。爲了測試,我在''行中放置了一些靜態文本,比如''將文本正確放置在屬性中,所以主體是正確的,它只是不通過參數傳遞值。 – paularmy42

+0

@ paularmy42:如何創建第二級文檔,然後通過unixy管道('|')將其傳遞給另一個xslt實例,以進行最終需要的更改? (只是粗略猜測我的部分!)。祝你們好運。 – shellter

+0

@ paularmy42在您的實際XSLT中,您可能有其他模板優先於標識模板,因此您也需要傳遞參數。 –