2017-03-09 64 views
-1

我有一個XML架構,其XML格式不規則/未格式化。該結構看起來像這 -用於從非線性XML結構中提取元素的XSLT

<Host> 
<element1>type0</element1> 
<element2>Fruits</element2> 
.... 
<elementn>Price0</elementn> 
    <Menu> 
    <NodeA> 
    <element1>type1</element1> 
    <element2>Fruits</element2> 
    .... 
    <elementn>Price1</elementn> 
    <Menu> 
    <NodeB> 
     <element1>type2</element1> 
     <element2>Fruits</element2> 
     .... 
     <elementn>Price2</elementn> 
     <Menu> 
     <NodeC> 
     <element1>type3</element1> 
     <element2>Fruits</element2> 
     .... 
     <elementn>Price3</elementn> 
     <Menu> 
     <NodeD> 
      <Element1>type4</element1> 
      <Element2>Vegetables</Element2> 
      .... 
      <Elementn>Price4</elementn> 
     </NodeD> 
     </Menu>  
     </NodeC> 
     </Menu> 
    </NodeB> 
    </Menu> 
    </NodeA> 
    <NodeE> 
    <element1>type5</element1> 
    <element2>Fruits</element2> 
    .... 
    <elementn>Price5</elementn> 
    <Menu> 
    <NodeF> 
     <element1>type6</element1> 
     <element2>Vegetables</element2> 
     .... 
     <elementn>Price6</elementn> 
    </NodeF> 
    </Menu> 
    </NodeE> 
    </Menu> 
</Host> 

現在我預期的XML如下 -

a)如果在所有節點<element2> ==水果,我需要的XML模式如下。我可以包含或排除右下主機下面的n個元素 -

`<element1>type0</element> 
<element2>Fruits</element2> 
.... 
<elementn>Price0</elementn>` 

。預計結果 -

<Host> 
    <NodeA> 
    <element1>type1</element1> 
    <element2>Fruits</element2> 
    .... 
    <elementn>Price1</elementn> 
    </NodeA> 
    <NodeB> 
    <element1>type2</element1> 
    <element2>Fruits</element2> 
    .... 
    <elementn>Price2</elementn> 
    </NodeB> 
    <NodeC> 
    <element1>type3</element1> 
    <element2>Fruits</element2> 
    .... 
    <elementn>Price3</elementn> 
    </NodeC> 
    <NodeE> 
    <element1>type5</element1> 
    <element2>Fruits</element2> 
    .... 
    <elementn>Price5</elementn> 
    </NodeE>  
</Host> 

二)如果在所有節點<element2> ==蔬菜,我需要的XML模式如下

注:<element2> ==蔬菜總是在架構中的最後一個節點

<Host> 
    <NodeD> 
    <element1>type4</element1> 
    <element2>Vegetables</element2> 
    .... 
    <elementn>Price4</elementn> 
    </NodeD>  
    <NodeF> 
    <element1>type6</element1> 
    <element2>Vegetables</element2> 
    .... 
    <elementn>Price6</elementn> 
    </NodeF> 
</Host> 

通過XSLT獲取上述XML格式的任何幫助都將非常有幫助。

+0

您的輸入或輸出都不是有效的XML,因此無法使用XML工具進行處理。此外,所有節點中的條件語句_「如果' == fruits',預期的XML將如下所示」_留下許多可能性,例如一些值爲'fruits',一些爲'vegetables'。這個問題還不清楚。 –

+0

仍然無效的XML。例如''沒有結束標籤。 –

+0

你的觀點(a)指的是'所有節點中的水果'情況。你的觀點(b)指的是「所有節點中的蔬菜」情況。但是你的XML既有水果也有蔬菜,所以(a)和(b)不適用。在XML既有水果又有蔬菜的情況下會發生什麼?你想要生成多個XML文檔嗎?或者他們是否應該在蔬菜前以水果的形式出現在相同的輸出中?謝謝。 –

回答

2

如果您需要2個單獨的文檔,您實際上不需要2個XSLT。您可以使用一個XSLT但參數

<xsl:param name="element2" select="'Fruits'" /> 

(以下'Fruits'只是默認值,如果參數不通過調用應用程序指定)。

你會開始通過選擇具有element2等於參數(待辦事項XML和XSLT是大小寫敏感的節點,所以element2是不一樣在你的XML Element2,但我以爲這是一個錯字你的XML)。

<xsl:apply-templates select="//*[element2=$element2]"/> 

您還需要一個模板,以確保當一個節點匹配,它不會複製子節點...

<xsl:template match="*[element2]"> 
    <xsl:copy> 
     <xsl:apply-templates select="*[not(*)]" /> 
    </xsl:copy> 
</xsl:template> 

其他節點將由身份模板來處理。

試試這個XSLT ...

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

    <xsl:param name="element2" select="'Fruits'" /> 

    <xsl:template match="/*"> 
     <xsl:copy> 
      <xsl:apply-templates select="//*[element2=$element2]" mode="copy"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="*[element2]" mode="copy"> 
     <xsl:copy> 
      <xsl:apply-templates select="*[not(*)]" mode="copy"/> 
     </xsl:copy> 
    </xsl:template> 

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

請注意,如果你使用XSLT 2.0,你可以在一個呼叫建立多個文檔,使用xsl:for-each-group得到不同的羣體,並xsl:result-document創建一個文件每。

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

    <xsl:template match="/*"> 
     <xsl:for-each-group select="//*[element2]" group-by="element2"> 
      <xsl:result-document href="{current-grouping-key()}.xml" method="xml"> 
       <Host> 
        <xsl:apply-templates select="current-group()" mode="copy" /> 
       </Host> 
      </xsl:result-document> 
     </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template match="*[element2]" mode="copy"> 
     <xsl:copy> 
      <xsl:apply-templates select="*[not(*)]" mode="copy"/> 
     </xsl:copy> 
    </xsl:template> 

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

我試圖第一XSLT和我看到錯誤 - 「歧義規則匹配/根 匹配兩者‘* [在element2]’上線的 12和‘/ *’上的第6行」 –

+0

我試圖第二XSLT,我看到一個錯誤 - '模糊規則匹配/根 匹配 行14上的「* [element2]」和' –

+0

第4行上的「/ *」我已經對我的答案進行了更正處理衝突的模板。 –