使用XSLT循环的XML到XML转换通过子节点

时间:2015-10-22 22:50:49

标签: xml xslt xsd

我刚刚开始使用XSLT并需要以下方面的帮助: -

这是我的XML: -

<?xml version="1.0" encoding="UTF-8"?>
<FMPXMLRESULT>
<METADATA>
  <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Site_ID" TYPE="TEXT" />
  <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Road_Name" TYPE="TEXT" />
  <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="KM" TYPE="NUMBER" />
</METADATA>
<RESULTSET FOUND="1">
  <ROW MODID="16" RECORDID="38664">
     <COL>
        <DATA>SI-3158</DATA>
     </COL>
     <COL>
        <DATA>Upper Taylor Main</DATA>
     </COL>
     <COL>
        <DATA>12.61</DATA>
     </COL>
  </ROW>
</RESULTSET>

在上面的XML中,第一个&#34; FIELD&#34;节点对应于第一个&#34; DATA&#34;的值。节点。我想以下面的方式转换上面的XML

<?xml version="1.0"?>
<COLUMN>
 <NAME>Site_ID</NAME>
 <TYPE>TEXT</TYPE>
 <NULLABLE>YES</NULLABLE>
 <MAXREPEAT>1</MAXREPEAT>
 <VALUE>SI-3158</VALUE>
</COLUMN>
<COLUMN>
 <NAME>Road_Name</NAME>
 <TYPE>TEXT</TYPE>
 <NULLABLE>YES</NULLABLE>
 <MAXREPEAT>1</MAXREPEAT>
 <VALUE>Upper Taylor Main</VALUE>
</COLUMN>
<COLUMN>
 <NAME>KM</NAME>
 <TYPE>NUMBER</TYPE>
 <NULLABLE>YES</NULLABLE>
 <MAXREPEAT>1</MAXREPEAT>
 <VALUE>12.61</VALUE>
</COLUMN>

以下是我到目前为止所做的事情: -

<xsl:stylesheet version="1.0"       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/FMPXMLRESULT/">
<xsl:for-each select="FIELD"> 
<COLUMN>
 <NAME><xsl:value-of select="@NAME"/></NAME>
 <TYPE><xsl:value-of select="@TYPE"/></TYPE>
 <NULLABLE><xsl:value-of select="@EMPTYOK"/></NULLABLE>
 <MAXREPEAT><xsl:value-of select="@MAXREPEAT"/></MAXREPEAT>
 <VALUE><xsl:value-of select="../../RESULTSET/ROW/COL/DATA"/></VALUE>
</COLUMN>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

首先使用我的XSLT值&#34;数据&#34;节点被添加到&#34; VALUE&#34;每个&#34; FIELD&#34;的属性,我需要循环遍历每个&#34; COL&#34;节点

其次,我看到各种帖子都没有建议使用&#34; xsl:for-each&#34;所以有更好的方法来完成我的需要。提前致谢

2 个答案:

答案 0 :(得分:2)

在您尝试的样式表中,您需要更改:

<xsl:template match="/FMPXMLRESULT/">
<xsl:for-each select="FIELD"> 

为:

<xsl:template match="/FMPXMLRESULT">
<xsl:for-each select="METADATA/FIELD"> 

使其按预期工作 - 除了值部分,需要通过其位置获取。

请注意,结果不是格式良好的XML文档,因为它没有单个根元素。

使用xsl:for-each进行此操作没有任何问题。

答案 1 :(得分:1)

试试这个:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml"/>
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="METADATA/FIELD">
        <COLUMN>
            <NAME>
                <xsl:value-of select="@NAME"/>
            </NAME>
            <TYPE>
                <xsl:value-of select="@TYPE"/>
            </TYPE>
            <NULLABLE>
                <xsl:value-of select="@EMPTYOK"/>
            </NULLABLE>
            <MAXREPEAT>
                <xsl:value-of select="@MAXREPEAT"/>
            </MAXREPEAT>
            <xsl:variable name="position" select="position() div 2"/>
            <VALUE>
                <xsl:value-of select="//FMPXMLRESULT/RESULTSET/ROW/COL[$position]/DATA"/>
            </VALUE>
        </COLUMN>
    </xsl:template>
    <xsl:template match="RESULTSET"/>    
</xsl:stylesheet>

这会产生所需的结果。无论何时,只要使用xsl:template而不是xsl:for-each。