2015-05-29 72 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