2015-05-29 62 views
0

有一個XML(用於XML被簡化的實例中)XSL文本節點的變換

<object attr1="1" attr2="2"> 
xxxxxxxxx 
    <someattrs> 
    <someattr1>a</someattr1> 
    <someattr2>b</someattr2> 
    <someattr3>c</someattr3> 
    <someattr4 attr3="3"> 
     yyyyyyy 
     <someattr5>d</someattr5> 
     <someattr6>e</someattr6> 
     <someattr7 attr8="f"> 
     <![CDATA[ zzzzzzz zzzzzz zzzzzz zzzzzzzzzzzz ]]> 
     </someattr7> 
    </someattr4> 
    </someattrs> 
</object> 

隨着XLS變換其目的是要變換具有屬性成元素爲中心的XML任何XML :

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="xml" indent="yes"/> 

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

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

的XML變換成

<?xml version="1.0" encoding="UTF-8"?> 
<object> 
    <attr1>1</attr1> 
    <attr2>2</attr2> 
    xxxxxxxxx 
    <someattrs> 
     <someattr1>a</someattr1> 
     <someattr2>b</someattr2> 
     <someattr3>c</someattr3> 
     <someattr4> 
     <attr3>3</attr3> 
     yyyyyyy 
     <someattr5>d</someattr5> 
     <someattr6>e</someattr6> 
     <someattr7> 
      <attr8>f</attr8> 
      zzzzzzz zzzzzz zzzzzz zzzzzzzzzzzz 
     </someattr7> 
     </someattr4> 
    </someattrs> 
</object> 

問題是任何出現在源xml中的自由文本()都沒有放入它自己的標記中(讓我們將所有自由文本放入名稱爲「sometext」的元素)放入最終xml中。文本「xxxxxxxxx」應該在其自己的標籤<sometext>xxxxxxxxx</sometext>中,「yyyyyyy」應該在其自己的標籤<sometext>yyyyyyy</sometext>中。

什麼是轉換以獲得以下XML?

<?xml version="1.0" encoding="UTF-8"?> 
<object> 
    <attr1>1</attr1> 
    <attr2>2</attr2> 
    <sometext>xxxxxxxxx</sometext> 
    <someattrs> 
     <someattr1>a</someattr1> 
     <someattr2>b</someattr2> 
     <someattr3>c</someattr3> 
     <someattr4> 
     <attr3>3</attr3> 
     <sometext>yyyyyyy</sometext> 
     <someattr5>d</someattr5> 
     <someattr6>e</someattr6> 
     <someattr7> 
      <attr8>f</attr8> 
      <sometext>zzzzzzz zzzzzz zzzzzz zzzzzzzzzzzz</sometext> 
     </someattr7> 
     </someattr4> 
    </someattrs> 
</object> 

回答

1

擺脫只格式化文本節點:

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

創建一個從純文本節點<sometext>元素。

<xsl:template match="object/text()"> 
    <sometext><xsl:value-of select="normalize-space(.)"/></sometext> 
</xsl:template> 

UPDATE

任何元素通用的解決方案:

<xsl:template match="*[*|@*]/text()"> 
    <sometext><xsl:value-of select="normalize-space(.)"/></sometext> 
</xsl:template> 
+0

泰爲帶狀空間。 :) xsl不能在匹配中使用「object」,因爲source xml不僅包含對象節點中的文本:(。'無 」(。)對象「 給出:'.... 一個 b ...'這是因爲過多它應該是'一個 b'。 – Willmore

+0

如何區分必須包含在''中的文本? – dlask

+0

如果元素具有「文本」和子元素,則文本應顯示爲元素「文本有一個文本(「xxxxxxxxx」)和元素 ...,這樣轉換後的文本應該出現在 xxxxxxxxx; 有文本(「yyyyyyy」)和子元素,, ...,這樣轉換後的文本應該出現在 yyyyyyy 。相反, a沒有子元素,所以它的文本(「a」)不應該出現在某些文本中。 Idk如何區分它們。:) – Willmore

1

你可以嘗試:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
    > 
    <xsl:output method="xml" indent="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="{name()}"><xsl:value-of select="."/></xsl:element> 
    </xsl:template> 

    <xsl:template match="*[@*]/text()"> 
     <sometext><xsl:value-of select="normalize-space(.)"/></sometext> 
    </xsl:template> 

</xsl:stylesheet> 
+0

ty :)。怎麼來''[@ *]'並且是相同的'* [* | @ *]'即給出相同的結果? – Willmore

+0

這意味着'* [*]'或'* [@ *]' –

+0

我在一個大的xml上測試了它,並給出了相同的結果:)。 – Willmore