XML 到 XML 使用 XSLT 的转换 - 在子节点上循环
XML to XML Transformation using XSLT- Loop over child nodes
我刚刚开始使用 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中第一个"FIELD"节点的值对应第一个"DATA"节点的值。我想用下面的方式 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 中,值第一个 "Data" 节点被添加到每个 "FIELD" 的 "VALUE" 属性中,我需要遍历每个 "COL" 节点。
其次我看到很多帖子都不推荐使用"xsl:for-each",请问有没有更好的可以完成我的需求。提前致谢
试试这个:
<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。
在您尝试的样式表中,您需要更改:
<xsl:template match="/FMPXMLRESULT/">
<xsl:for-each select="FIELD">
至:
<xsl:template match="/FMPXMLRESULT">
<xsl:for-each select="METADATA/FIELD">
使其按预期工作 - 除了值部分,需要按其位置获取。
请注意,结果不是格式正确的 XML 文档,因为它没有单个根元素。
为此使用 xsl:for-each
没有错。
我刚刚开始使用 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中第一个"FIELD"节点的值对应第一个"DATA"节点的值。我想用下面的方式 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 中,值第一个 "Data" 节点被添加到每个 "FIELD" 的 "VALUE" 属性中,我需要遍历每个 "COL" 节点。
其次我看到很多帖子都不推荐使用"xsl:for-each",请问有没有更好的可以完成我的需求。提前致谢
试试这个:
<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。
在您尝试的样式表中,您需要更改:
<xsl:template match="/FMPXMLRESULT/">
<xsl:for-each select="FIELD">
至:
<xsl:template match="/FMPXMLRESULT">
<xsl:for-each select="METADATA/FIELD">
使其按预期工作 - 除了值部分,需要按其位置获取。
请注意,结果不是格式正确的 XML 文档,因为它没有单个根元素。
为此使用 xsl:for-each
没有错。