2014-03-07 35 views
0

我有一個關於XSLT的問題。我是一個新手。閱讀論壇並試圖獲得所需的XML格式輸出。XSLT將複雜的實時XML轉換爲有意義的平面XML

如您所見,根據$<DataSources>標籤屬性TYPEID,其子NODES有所不同。

我想在這裏實現的是

  1. FLATTEN XML的層次
  2. 了把某些標記
  3. 轉換標籤,如<expression>又包含其他子節點或標籤,而不是一個TEXT()值,以這種格式

    (AND)的表達。((((EventDisplayNumber)(等於)(823)))... ..和等

到目前爲止,我只能將所有屬性轉換爲ELEMENTS,作爲平展XML的第一步。

下一步是打破heirarchy並將深嵌套的XML標籤轉換爲數學符號的符號表達式。

第三種方法是從以前的輸出中選擇所需的NODES。

請建議或幫助,因爲我完全難以接受,因此我應該如何繼續下一步。

輸入::

<Rule ID="SpaceLeftPercent." Enabled="true" Target="DBFileGroup" > 
    <Category>PerformanceCollection</Category> 
    <DataSources> 
     <DataSource ID="DS" TypeID="DBFileGroupSizeOptimizedPerfProvider"> 
      <IntervalSeconds>900</IntervalSeconds> 
      <SyncTime /> 
      <ConnectionString> ConnectionString$</ConnectionString> 
      <ServerName> NetworkName$</ServerName> 
      <SqlInstanceName> InstanceName$</SqlInstanceName> 
      <ObjectName> PerformanceCounterObject$ : Database : File Group</ObjectName> 
      <CounterName>DB File Group Allocated Space Left (%)</CounterName> 
      <InstanceName> GroupName$</InstanceName> 
      <DatabaseName> DatabaseName$</DatabaseName> 
      <DBFileGroupId>GroupID$</DBFileGroupId> 
      <Value>$Data/Property[@Name='FreeSpaceAutoGrowPercent']$</Value> 
      <Tolerance>10</Tolerance> 
      <ToleranceType>Absolute</ToleranceType> 
      <MaximumSampleSeparation>4</MaximumSampleSeparation> 
      <TimeoutSeconds>300</TimeoutSeconds> 
     </DataSource> 
    </DataSources> 
</Rule> 

<Rule ID=" id823" Enabled="true" ConfirmDelivery="true" Remotable="true" > 
    <Category>EventCollection</Category> 
    <DataSources> 
     <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.EventProvider"> 
      <ComputerName>NetworkName$</ComputerName> 
      <LogName>Application</LogName> 
      <Expression> 
       <And> 
        <Expression> 
         <SimpleExpression> 
          <ValueExpression> 
           <XPathQuery Type="UnsignedInteger">EventDisplayNumber</XPathQuery> 
          </ValueExpression> 
          <Operator>Equal</Operator> 
          <ValueExpression> 
           <Value Type="UnsignedInteger">823</Value> 
          </ValueExpression> 
         </SimpleExpression> 
        </Expression> 
        <Expression> 
         <SimpleExpression> 
          <ValueExpression> 
           <XPathQuery Type="String">PublisherName</XPathQuery> 
          </ValueExpression> 
          <Operator>Equal</Operator> 
          <ValueExpression> 
           <Value Type="String"> ServiceName$</Value> 
          </ValueExpression> 
         </SimpleExpression> 
        </Expression> 
       </And> 
      </Expression> 
     </DataSource> 
    </DataSources> 
    <WriteActions> 
     <WriteAction > 
      <Priority>2</Priority> 
      <Severity>2</Severity> 
      <AlertName /> 
      <AlertDescription /> 
      <AlertOwner /> 

      <AlertParameters> 
       <AlertParameter1>$Data/EventDescription$</AlertParameter1> 
      </AlertParameters> 
      <Suppression> 
       <SuppressionValue /> 
      </Suppression> 

     </WriteAction> 
    </WriteActions> 
</Rule> 

我目前的XSL:

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

    <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="/*/Rule/DataSources/DataSource"> 
     <xsl:element name="{local-name()}"> 
      <xsl:value-of select="."/> 
     </xsl:element> 
     <xsl:apply-templates select="node()"/> 
    </xsl:template> 

    <xsl:template name="resolveexpr" match="/*/Rule/DataSources/DataSource"> 
     <xsl:choose> 
      <xsl:when test="contains(name(.),'Expression')"> 
       <xsl:text>sometext</xsl:text> 
      </xsl:when>  
      <xsl:otherwise /> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

輸出DESIRED: 類似下面。 但是我的最終目標是把它帶入Excel表格。

<Rule> 
    <ID>id823</ID> 
    <Enabled>true</Enabled> 
    <ConfirmDelivery>true</ConfirmDelivery> 
    <Remotable>true</Remotable > 
    <Category>EventCollection</Category> 
    <DataSources> 
    <DataSource> 
     <TypeID>Windows!Microsoft.Windows.EventProvider> 
     <ComputerName>NetworkName$</ComputerName> 
     <LogName>Application</LogName> 
     <Expression> 
     <And>((((EventDisplayNumber))(Equal)((823))))((((PublisherName))(Equal)((ServiceName$))))</And> 
     </Expression> 
    </DataSource> 
    </DataSources> 
    <WriteActions> 
    <WriteAction > 
     <Priority>2</Priority> 
     <Severity>2</Severity> 
     <AlertParameters> 
     <AlertParameter1>$Data/EventDescription$</AlertParameter1> 
     </AlertParameters> 
     <Suppression> 
     <SuppressionValue /> 
     </Suppression> 
    </WriteAction> 
    </WriteActions> 
</Rule> 
+2

你能在這種情況下顯示你期望的輸出嗎?如果您也縮減了XML樣本,它也可能有所幫助。謝謝! –

+0

單位通常沒有意義。層次結構傳達上下文。 – keshlam

+0

@Tim我添加了所需的輸出,也是縮進的。 – user3391883

回答

0

雖然從您想要將屬性轉換爲元素的示例看起來已經開始使用標識模板。因此,您需要從身份模板匹配中移除@*模式,並創建另一個模板以匹配屬性。

<xsl:template match="@*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:value-of select="."/> 
    </xsl:element> 
</xsl:template> 

您需要的其他模板可能與建立表達式有關。你並沒有真正解釋完整的邏輯,但它看起來像是輸出由圓括號包圍的值的情況。這樣

<xsl:template match="SimpleExpression"> 
    <xsl:text>(</xsl:text> 
     <xsl:apply-templates /> 
    <xsl:text>)</xsl:text> 
</xsl:template> 

<xsl:template match="ValueExpression|Operator"> 
    <xsl:text>(</xsl:text> 
     <xsl:value-of select="." /> 
    <xsl:text>)</xsl:text> 
</xsl:template> 

東西它也像你只是想輸出的最上面的表達元素,所以你需要一個模板,任何後代的人跳過

<xsl:template match="Expression[ancestor::Expression]"> 
     <xsl:apply-templates /> 
</xsl:template> 

元素,如將被身份轉換舀起。

試試這個XSLT。這可能不會給你正是你需要的東西,但它應該給你更多的開始指引你的方式:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="@*"> 
     <xsl:element name="{local-name()}"> 
      <xsl:value-of select="."/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="Expression[ancestor::Expression]"> 
      <xsl:apply-templates /> 
    </xsl:template> 

    <xsl:template match="SimpleExpression"> 
     <xsl:text>(</xsl:text> 
      <xsl:apply-templates /> 
     <xsl:text>)</xsl:text> 
    </xsl:template> 

     <xsl:template match="ValueExpression|Operator"> 
     <xsl:text>(</xsl:text> 
      <xsl:value-of select="." /> 
     <xsl:text>)</xsl:text> 
    </xsl:template> 
</xsl:stylesheet>