2016-01-04 41 views
2

我試圖將一個節點的節點內容複製到另一個節點。基本上,節點內容應該與第一個節點中的內容相同,除了不應該替換第二個節點中的引號。節點到節點的XSLT/XML拷貝值

我發現了一些代碼並對其進行了修改,但它只複製了第一個節點內容的第一個外觀。

這是我到目前爲止的xslt代碼。

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:param name="pReplacement" select="/strings/string/de/text()"/> 

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

    <xsl:template match="strings/string/es/text()"> 
    <xsl:value-of select="$pReplacement"/> 
    </xsl:template> 
</xsl:stylesheet> 

輸入XML是:

<?xml version="1.0"?> 
<?xml-stylesheet href="test.xsl" type="text/xsl"?> 
    <strings> 
    <string name="cpu"> 
     <en>example1</en> 
     <de>something1</de> 
     <es>""</es> 
    </string> 
    <string name="gpu"> 
     <en>example2</en> 
     <de>something2</de> 
     <es>""</es> 
    </string> 
    <string name="mainboard"> 
     <en>example3</en> 
     <de>something3</de> 
     <es>""</es> 
    </string> 
</strings> 

錯誤的輸出是:

<?xml-stylesheet href="test.xsl" type="text/xsl"?><strings> 
    <string name="cpu"> 
    <en>example1</en> 
    <de>something1</de> 
    <es>something1</es> 
    </string> 
    <string name="gpu"> 
    <en>example2</en> 
    <de>something2</de> 
    <es>something1</es> 
    </string> 
    <string name="mainboard"> 
    <en>example3</en> 
    <de>something3</de> 
    <es>something1</es> 
    </string> 
</strings> 

所需的輸出應該是這樣的。

<?xml-stylesheet href="test.xsl" type="text/xsl"?><strings> 
    <string name="cpu"> 
    <en>example1</en> 
    <de>something1</de> 
    <es>"something1"</es> 
    </string> 
    <string name="gpu"> 
    <en>example2</en> 
    <de>something2</de> 
    <es>"something2"</es> 
    </string> 
    <string name="mainboard"> 
    <en>example3</en> 
    <de>something3</de> 
    <es>"something3"</es> 
    </string> 
</strings> 

也許有人可以幫助我找到一個解決方案或指向正確的方向。

提前感謝

回答

1

你的方法是行不通的,因爲XPath表達式

/strings/string/de/text() 

幾個結果,三年在這種情況下。如果你把它們放在一個參數是這樣的:

<xsl:param name="pReplacement" select="/strings/string/de/text()"/> 

然後所有 3結果節點將成爲pReplacement一部分。如果您在

<xsl:value-of select="$pReplacement"/> 

然後用一組節點在只有一個節點預計的地方,象只第一節點將被選中進行此項操作。

沒有多少,你必須改變,只是頂層參數廢除和替換的strings/string/es/text()內容與

<xsl:value-of select="../../de"/> 

XSLT樣式表

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="strings/string/es/text()"> 
    <xsl:value-of select="../../de"/> 
    </xsl:template> 

</xsl:stylesheet> 

XML輸出

<strings> 
    <string name="cpu"> 
     <en>example1</en> 
     <de>something1</de> 
     <es>something1</es> 
    </string> 
    <string name="gpu"> 
     <en>example2</en> 
     <de>something2</de> 
     <es>something2</es> 
    </string> 
    <string name="mainboard"> 
     <en>example3</en> 
     <de>something3</de> 
     <es>something3</es> 
    </string> 
</strings> 

試試這個解決方案在線here


編輯

如果你的文檔中的所有es元素應該由這個變化的影響,你也可以寫模板

<xsl:template match="es/text()"> 
    <xsl:value-of select="../preceding-sibling::de"/> 
</xsl:template> 

但是這需要有總是一個de元素作爲string元素的子元素,並且它始終在es元素之前。最後,如果在es元素之前有幾個de元素,如果您使用的是XSLT 2.0,則這可能會成爲問題,因爲它將簡單地連接所有前面的de元素的字符串值。

+1

@Parfait我們不知道這是否合理。許多人在SO上展示的XML文檔都是「真實」問題的精簡版本。也許在'strings/string/es'之外的地方有'es'元素不應該受到這個模板的影響。這可能是一個好主意,但我們不知道。 –

+0

非常感謝您的快速,詳細和專業的答案。你是完全正確的。它是xml的精簡版本,但在這種情況下,「es」元素不在其他位置。並且還要感謝與在線xsl編輯器的提示,它使得我的測試速度更快。 – Cali

+0

當然,我必須感謝你。 – Cali