2017-04-18 69 views
0

我試圖使用XSLT將XML從一種格式轉換爲另一種格式,但這很複雜(至少對我來說),我不知道如何繼續。我需要做以下邏輯:使用XSLT 1.0對XML進行非平凡的轉換

(寫在C#的僞代碼)

  1. 更新基於第四軸元素的內容(如果存在的話),每臺機器的頂部元素,但只當Type子元素的內容具有值「Rotary」時。如果這一條件得到滿足,則頂部的格式應該是這樣:

    <Top> 
        <Axis>xxx</Axis> 
        <IsIndexed>false</IsIndexed> 
        <IsManual>false</IsManual> 
    </Top> 
    

其中xxx將是AxisID/name元素的值。

  1. 使用與第1項所述相同的條件替換內容,不同之處在於將檢查第五個軸元素(與第1項中檢查的第4項)。

  2. 根據每臺機器的第四個和第五個Axis元素的內容更新Mode元素。如果第四軸和第五軸的類型元素的值爲旋轉,則模式的值爲256.如果其中只有一個旋轉的值,則模式的值爲128.如果旋轉的值均不是,則值模式元素應爲0.

  3. 刪除當前的Ordering,IsIndexed和IsManual元素。這一個目前正在實現,但我不知道這是否會需要根據我在1-3

XSLT上面列出了新的要求改變:(我目前有)

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:cd="http://schemas.datacontract.org/2004/07/CMachine" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <xsl:output method="xml" indent="yes" /> 
    <!-- Copy everything not subject to the exceptions below --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Ignore the ordering IsIndexed, IsManual elements --> 
    <xsl:template match="cd:Ordering|cd:IsIndexed|cd:IsManual" /> 

</xsl:stylesheet> 

輸入:

<?xml version="1.0" encoding="utf-8"?> 
<ArrayOfMachine xmlns="http://schemas.datacontract.org/2004/07/CMachine" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <Machine> 
    <Price>120000</Price> 
    <Properties> 
     <Axes> 
     <Axis> 
      <AxisID> 
      <Name>X</Name> 
      <Type>X</Type> 
      </AxisID> 
      <Type>Linear</Type> 
     </Axis> 
     <Axis> 
      <AxisID> 
      <Name>Y</Name> 
      <Type>Y</Type> 
      </AxisID> 
      <Type>Linear</Type> 
     </Axis> 
     <Axis> 
      <AxisID> 
      <Name>Z</Name> 
      <Type>Z</Type> 
      </AxisID> 
      <Type>Linear</Type> 
     </Axis> 
     <Axis> 
      <AxisID> 
      <Name>R1</Name> 
      <Type>B</Type> 
      </AxisID> 
      <Type>Rotary</Type> 
     </Axis> 
     <Axis> 
      <AxisID> 
      <Name>R2</Name> 
      <Type>C</Type> 
      </AxisID> 
      <Type>Linear</Type> 
     </Axis> 
     </Axes> 
     <Ordering>XR1YR2Z</Ordering> 
     <Rotaries> 
     <Top i:nil="true" /> 
     <Bottom i:nil="true"/> 
     <IsIndexed>false</IsIndexed> 
     <IsManual>false</IsManual> 
     <Mode>222</Mode> 
     </Rotaries> 
    </Properties> 
    </Machine> 
</ArrayOfMachine> 

所需的輸出:

<?xml version="1.0" encoding="utf-8"?> 
<ArrayOfMachine xmlns="http://schemas.datacontract.org/2004/07/CMachine" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <Machine> 
    <Price>120000</Price> 
    <Properties> 
     <Axes> 
     <Axis> 
      <AxisID> 
      <Name>X</Name> 
     <Type>X</Type> 
      </AxisID> 
      <Type>Linear</Type> 
     </Axis> 
     <Axis> 
      <AxisID> 
      <Name>Y</Name> 
      <Type>Y</Type> 
      </AxisID> 
      <Type>Linear</Type> 
     </Axis> 
     <Axis> 
      <AxisID> 
      <Name>Z</Name> 
      <Type>Z</Type> 
      </AxisID> 
      <Type>Linear</Type> 
     </Axis> 
     <Axis> 
      <AxisID> 
      <Name>R1</Name> 
      <Type>B</Type> 
      </AxisID> 
      <Type>Rotary</Type> 
     </Axis> 
     <Axis> 
      <AxisID> 
      <Name>R2</Name> 
      <Type>C</Type> 
      </AxisID> 
      <Type>Linear</Type> 
     </Axis> 
     </Axes> 
     <Ordering>XR1YR2Z</Ordering> 
     <Rotaries> 
     <Top> 
      <Axis>R1</Axis> 
        <IsIndexed>false</IsIndexed> 
        <IsManual>false</IsManual> 
     </Top> 
     <Bottom i:nil="true" /> 
     <Mode>128</Mode> 
     </Rotaries> 
    </Properties> 
    </Machine> 
</ArrayOfMachine> 

任何幫助將不勝感激!

+0

我不明白你的僞代碼 - 請說明用簡單的英語所需的邏輯。 –

+0

@ michael.hor257k我試圖更加清楚。讓我知道是否仍有含糊之處。 – markf78

回答

1

以下是修改MachineTop元素的示例,該元素的第4個AxisType值爲"Rotary"。新的Axis元素的值取自所述AxisAxisID/Name元素。

我相信你應該能夠擴展到其他兩項任務。

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:cd="http://schemas.datacontract.org/2004/07/CMachine" 
xmlns="http://schemas.datacontract.org/2004/07/CMachine" 
exclude-result-prefixes="cd"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="cd:Machine/cd:Properties[cd:Axes/cd:Axis[4]/cd:Type='Rotary']/cd:Rotaries/cd:Top"> 
    <xsl:copy> 
     <Axis> 
      <xsl:value-of select="ancestor::cd:Properties/cd:Axes/cd:Axis[4]/cd:AxisID/cd:Name"/> 
     </Axis> 
     <IsIndexed>false</IsIndexed> 
     <IsManual>false</IsManual> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

這個答案似乎解決了除了項目3以外的所有問題。不知道如何處理Rotary類型的軸的數量計算,然後根據該數量設置元素的值。 – markf78

+0

計算任何和所有類型爲旋轉的軸都足夠了嗎?或者是否有必要將計數限制爲只有這種類型的#4和#5軸? –

+0

總數。此外,如果我想修改頂部元素來表示符合此條件的第一個軸,它將是cd:Machine/cd:Properties [cd:Axes/cd:Axis/cd:Type ='Rotary'] [1]/CD:旋轉開關/ CD:前?而且,如果是這樣,聲明的價值是什麼?如果這更合適,我可以將其作爲一個單獨的問題。 – markf78