2016-09-19 98 views
0

我有一個xpaths的源和目標列表,其中每個列表都基於他們自己的模式。對於每個源路徑都存在一個目標路徑。例如,我有源列表[/ shiporder/shipfrom/name,/ shiporder/address/city]和目錄列表[/ root/Seller/Country],其中列表的順序連接源與目標路徑的路徑。現在我可以創建簡單易讀的樣式表,它應用每個源路徑並針對目標路徑創建輸出。對於/運送訂單/ shipfrom /名稱stylesheet是:通過xpath列表創建xml文件

<xsl:template match="/"> 
     <xsl:apply-templates select="shiporder"/> 
    </xsl:template> 
<xsl:template match="/shiporder"> 
<root> 
     <xsl:apply-templates select="shipfrom"/> 
</root> 
</xsl:template> 
<xsl:template match="/shiporder/shipfrom"> 
    <Seller> 
     <xsl:apply-templates select="name"/> 
    </Seller> 
</xsl:template> 
<xsl:template match="/shiporder/shipfrom/name"> 
    <Country> 
     <xsl:apply-templates select="text()"/> 
    </Country> 
</xsl:template> 

/shiporder/address/citystylesheet是:

<xsl:template match="/"> 
     <xsl:apply-templates select="shiporder"/> 
    </xsl:template> 
<xsl:template match="/shiporder"> 
<root> 
     <xsl:apply-templates select="address"/> 
</root> 
</xsl:template> 
<xsl:template match="/shiporder/address"> 
    <Seller> 
     <xsl:apply-templates select="city"/>   
    </Seller> 
</xsl:template> 
<xsl:template match="/shiporder/address/city"> 
    <City> 
     <xsl:apply-templates select="text()"/> 
    </City> 
</xsl:template> 

創作後,我上的任意源XML文件同時應用樣式基於源模式如:

<shiporder> 
    <shipfrom> 
    <name>orderperson1</name> 
    </shipfrom> 
    <address> 
    <city>London</city> 
    </address> 
    <address> 
    <city>Berlin</city> 
    </address> 
</shiporder> 

現在我喜歡將兩個樣式表儘可能簡單地組合到一個stylesheet

+2

對不起,你的問題不是很清楚。請顯示兩個不同的XML輸入和每個輸入的期望輸出。 –

+0

@JimGarrison我試圖簡化我的問題,讓我知道如果有什麼不清楚。如果你對標題有更好的建議,也請告訴我。 – StellaMaris

+0

如果所有元素都存在,您的預期輸出是什麼?如在你的示例輸入XML中一樣? –

回答

0

從我在你的問題理解的基礎,我想出了這樣的事情:

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

    <xsl:strip-space elements="*"/> 
    <xsl:output indent="yes"/> 

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

    <xsl:template match="shiporder"> 
     <root> 
      <xsl:apply-templates/> 
     </root> 
    </xsl:template> 

    <xsl:template match="address"> 
     <!-- store the name node to a variable --> 
     <xsl:variable name="country" select="../shipfrom/name"/> 
     <Seller> 
      <xsl:apply-templates/> 
      <!-- check if the variable is not empty, 
       if not, output the contents under the node Country --> 
      <xsl:if test="normalize-space($country)!=''"> 
       <Country> 
        <xsl:value-of select="$country"/> 
       </Country> 
      </xsl:if> 
     </Seller> 
    </xsl:template> 

    <xsl:template match="city"> 
     <City> 
      <xsl:apply-templates/> 
     </City> 
    </xsl:template> 

    <xsl:template match="shipfrom"> 
     <xsl:choose> 
      <!-- check for following-sibling address nodes, 
       if none found, delete the node --> 
      <xsl:when test="following-sibling::address"/> 
      <xsl:otherwise> 
       <Seller> 
        <xsl:apply-templates/> 
       </Seller> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template match="shipfrom/name"> 
     <Country> 
      <xsl:apply-templates/> 
     </Country> 
    </xsl:template> 

</xsl:stylesheet> 
0

你的第一個樣式表輸出下面的XML文件:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <Seller> 
     <Country>orderperson1</Country> 
    </Seller> 
</root> 

而且你的第二個樣式表輸出如下因素XML文件:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <Seller> 
     <City>London</City> 
    </Seller> 
    <Seller> 
     <City>Berlin</City> 
    </Seller> 
</root> 

如果要生成兩個輸出結果b在一個樣式表模塊中,您應該引入控制輸出的參數xsl:param。我製作了實現此要求的最小樣式表。

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

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

    <xsl:param name="prmOutputShipForm" select="'yes'"/> 
    <xsl:variable name="pOutputShipForm" select="$prmOutputShipForm = 'yes'"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="shiporder"/> 
    </xsl:template> 

    <xsl:template match="/shiporder"> 
     <root> 
      <xsl:choose> 
       <xsl:when test="$pOutputShipForm"> 
        <xsl:apply-templates select="shipfrom"/> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:apply-templates select="address"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </root> 
    </xsl:template> 

    <xsl:template match="/shiporder/shipfrom"> 
     <Seller> 
      <xsl:apply-templates select="name"/> 
     </Seller> 
    </xsl:template> 

    <xsl:template match="/shiporder/shipfrom/name"> 
     <Country> 
      <xsl:apply-templates/> 
     </Country> 
    </xsl:template> 

    <xsl:template match="/shiporder/address"> 
     <Seller> 
      <xsl:apply-templates select="city"/>   
     </Seller> 
    </xsl:template> 

    <xsl:template match="/shiporder/address/city"> 
     <City> 
      <xsl:apply-templates/> 
     </City> 
    </xsl:template> 

</xsl:stylesheet> 

通過設置OutputShipForm =「yes/no」,可以控制輸出XML結果。

+0

Thx tmakita,但它正在尋找別的東西,因爲假設我有一個第三''/ shiporder/elem3/xy'和第四''/ shiporder/elem4/xy'元素,我想以相同的方式添加分支變得複雜。 – StellaMaris

+0

@StellaMaris您能指定想要處理的具體輸入XML文件嗎?我認爲上面的樣式表修改至少適用於您的輸入XML示例。 – tmakita

+0

源xml文件可以是任意的,你至少會找到根節點'shiporder'。在源列表中以xpath形式給出的所有其他元素不是必需的,但可能會在源xml中找到它們。 – StellaMaris