2013-01-16 98 views
0

我對XML數據的結構如下改造:XSLT/XPath的更換特定節點

<root> 
     <main1> 
      <page> 
       <text-body> 
        <title>K1</title> 
        <subtitle>Text</subtitle> 
       </text-body> 
       <text-body> 
        <title>Text</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
       <text-body> 
        <title>Text</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
      </page> 
      <page> 
       <text-body> 
        <title>K2</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
       <text-body> 
        <title>Text</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
      </page> 
      <page> 
       <text-body> 
        <title>K3</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
       <text-body> 
        <title>Text</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
      </page> 
     </main1> 
     <main2> 
      <text-body> 
       <title>B</title> 
       <subtitle>B</subtitle> 
       <body>B</body> 
      </text-body> 
      <text-body> 
       <title>C</title> 
       <subtitle>C</subtitle> 
       <body>C</body> 
      </text-body> 
      <text-body> 
       <title>D</title> 
       <subtitle>D</subtitle> 
       <body>D</body> 
      </text-body> 
     </main2> 
</root> 

我需要用頭銜K1替換MAIN1 /文本主體中的數據,K2,K3與數據在main2/text-body中,但將其他文本主體元素保留在main1中。輸出應該是這樣的:

<root> 
     <main1> 
      <page> 
       <text-body> 
        <title>B</title> 
        <subtitle>B</subtitle> 
        <body>B</body> 
       </text-body> 
       <text-body> 
        <title>Text</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
       <text-body> 
        <title>Text</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
      </page> 
      <page> 
       <text-body> 
        <title>C</title> 
        <subtitle>C</subtitle> 
        <body>C</body> 
       </text-body> 
       <text-body> 
        <title>Text</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
      </page> 
      <page> 
       <text-body> 
        <title>D</title> 
        <subtitle>D</subtitle> 
        <body>D</body> 
       </text-body> 
       <text-body> 
        <title>Text</title> 
        <subtitel>Text</subtitel> 
       </text-body> 
      </page> 
     </main1> 
     <main2> 
      <text-body> 
       <title>B</title> 
       <subtitle>B</subtitle> 
       <body>B</body> 
      </text-body> 
      <text-body> 
       <title>C</title> 
       <subtitle>C</subtitle> 
       <body>C</body> 
      </text-body> 
      <text-body> 
       <title>D</title> 
       <subtitle>D</subtitle> 
       <body>D</body> 
      </text-body> 
     </main2> 
</root> 

我有以下XSL-代碼:

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

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

     <xsl:template match="main1/page/text-body"> 
      <xsl:param name="count" select="title/substring(.,2,1)"/> 
      <xsl:if test="title/substring(.,1,1)='K'"> 
       <xsl:copy-of select="/root/main2/text-body[$count]"/> 
      </xsl:if> 
     </xsl:template> 

    </xsl:stylesheet> 

我儘量選擇在標題和檢查的人數,如果在文本A K 。但它不起作用。而且我不知道如何保留其他文本元素。這裏是當前輸出:

<main1> 
      <page> 
       <text-body> 
       <title>B</title> 
       <subtitle>B</subtitle> 
       <body>B</body> 
      </text-body><text-body> 
       <title>C</title> 
       <subtitle>C</subtitle> 
       <body>C</body> 
      </text-body><text-body> 
       <title>D</title> 
       <subtitle>D</subtitle> 
       <body>D</body> 
      </text-body> 


      </page> 
      <page> 
       <text-body> 
       <title>B</title> 
       <subtitle>B</subtitle> 
       <body>B</body> 
      </text-body><text-body> 
       <title>C</title> 
       <subtitle>C</subtitle> 
       <body>C</body> 
      </text-body><text-body> 
       <title>D</title> 
       <subtitle>D</subtitle> 
       <body>D</body> 
      </text-body> 

      </page> 
      <page> 
       <text-body> 
       <title>B</title> 
       <subtitle>B</subtitle> 
       <body>B</body> 
      </text-body><text-body> 
       <title>C</title> 
       <subtitle>C</subtitle> 
       <body>C</body> 
      </text-body><text-body> 
       <title>D</title> 
       <subtitle>D</subtitle> 
       <body>D</body> 
      </text-body> 

      </page> 
     </main1> 
     <main2> 
      <text-body> 
       <title>B</title> 
       <subtitle>B</subtitle> 
       <body>B</body> 
      </text-body> 
      <text-body> 
       <title>C</title> 
       <subtitle>C</subtitle> 
       <body>C</body> 
      </text-body> 
      <text-body> 
       <title>D</title> 
       <subtitle>D</subtitle> 
       <body>D</body> 
      </text-body> 
     </main2> 
</root> 

請幫忙!

回答

0

的主要問題是,你的計數參數被設置爲一個字符串,但如果你想在使用作爲一個索引,它應該是一個數字,所以你需要做到這一點

<xsl:copy-of select="/root/main2/text-body[number($count)]"/> 

而且,你可能不希望使用XSL:如果這裏,因爲目前的範本,也不會輸出text-body元素當if條件爲false時。實際上,您應該將測試移動到模板匹配的一部分。

<xsl:template match="main1/page/text-body[title/substring(.,1,1)='K']"> 

下面是完整的XSLT

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

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

    <xsl:template match="main1/page/text-body[title/substring(.,1,1)='K']"> 
     <xsl:param name="count" select="title/substring(.,2,1)"/> 
     <xsl:copy-of select="/root/main2/text-body[number($count)]"/> 
    </xsl:template> 
</xsl:stylesheet> 

這應該出示你的預期輸出。

如果你有興趣在一個不同的方法,你可以選擇定義一個XSL:關鍵來查找MAIN2 /文本體元素

<xsl:key name="main2" 
    match="main2/text-body" 
    use="concat('K', count(preceding-sibling::text-body) + 1)" /> 

這樣的話,你可以刪除需要通過子使用下面的模板爲MAIN1 /頁/文本體匹配元素,而不是

<xsl:template match="main1/page/text-body[key('main2', title)]"> 
    <xsl:copy-of select="key('main2', title)"/> 
</xsl:template> 
+0

根據我的經驗,像'噸itle/substring(。,2,1)'在XSLT 2.0中運行良好。什麼反對這樣做? –

+0

你是對的。我愚蠢地使用XSLT1.0處理器來測試我的答案!我已經修改了我的答案,以刪除有關錯誤的子字符串的位。 –

+0

非常感謝! –

0

使用謂詞來僅匹配您想要交換的text-body元素。當你正在使用XSLT 2.0,您可以在謂詞中使用正則表達式:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output method="xml"/> 

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

    <xsl:template match="main1/page/text-body[matches(title,'^K\d+$')]"> 
    <xsl:variable name="count" select="xs:integer(title/substring(.,2))"/> 
    <xsl:copy-of select="/root/main2/text-body[$count]"/> 
    </xsl:template> 

</xsl:stylesheet>