我是XSLT的新手,所以这可能是非常基本的,但我真的很感激一些输入。我需要转换我的xml中的子节点,但同时保持父节点不变。我的xml看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XMLTest xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:jfxpf="http://www.xfa.com/schema/xml-package" xmlns:xfa="http://www.xfa.com/schema/xfa-data">
<result form="10" version="4" resultid="23146" respondent="ycisxmir" authid="" date="2012-09-12 06:39:44" times="462">
<Q0061 answerid="1">1</Q0061>
<Q0060 answerid="2">2</Q0060>
<QTXT1>1</QTXT1>
</result>
</XMLTest>
我需要保持两个顶级节点XMLTest并且结果不变,而子节点需要转换为更通用的格式,如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XMLTest xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:jfxpf="http://www.xfa.com/schema/xml-package" xmlns:xfa="http://www.xfa.com/schema/xfa-data">
<result form="10" version="4" resultid="23146" respondent="ycisxmir" authid="" date="2012-09-12 06:39:44" times="462">
<answer>Q0061</answer>
<id>1</id>
<value>1</value>
<answer>Q0060</answer>
<id>2</id>
<value>2</value>
<answer>QTXT1</answer>
<value>1</value>
</result>
</XMLTest>
到目前为止,我的xslt看起来像这样:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="result/*">
<answer><xsl:value-of select="local-name()"/></answer>
<id><xsl:value-of select="@answerid"/></id>
<value><xsl:value-of select="@*"/></value>
</xsl:template>
</xsl:stylesheet>
我尝试在顶级节点上使用xsl:copy,但是在不丢失子节点或子节点转换的情况下无法使其工作。如何保持顶部节点并同时强制通过我已转换的子节点?
答案 0 :(得分:3)
从
开始<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
现在为您需要的转换添加模板,例如
<xsl:template match="result/*[@answerid]">
<answer><xsl:value-of select="local-name()"/></answer>
<id><xsl:value-of select="@answerid"/></id>
<value><xsl:value-of select="."/></value>
</xsl:template>
<xsl:template match="result/*[not(@answerid)]">
<answer><xsl:value-of select="local-name()"/></answer>
<value><xsl:value-of select="."/></value>
</xsl:template>
答案 1 :(得分:1)
您缺少身份模板:
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
我已经纠正了你的答案..:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/XMLTest/result/*">
<answer>
<xsl:value-of select="local-name()"/>
</answer>
<id>
<xsl:value-of select="@answerid"/>
</id>
<value>
<xsl:value-of select="@*"/>
</value>
</xsl:template>
</xsl:stylesheet>
<强> EDIT1:强> 如果属性为null,则更新模板以丢弃:if条件在将属性转换为元素之前检查属性是否为空。
<xsl:template match="/XMLTest/result/*">
<answer>
<xsl:value-of select="local-name()"/>
</answer>
<xsl:if test="@answerid/.!=''">
<id>
<xsl:value-of select="@answerid"/>
</id>
</xsl:if>
<xsl:if test="@*/.!=''">
<value>
<xsl:value-of select="@*"/>
</value>
</xsl:if>
</xsl:template>
Edit2:在你的早期尝试中,你试图复制@ *的值,@*
表示任何名称的属性,所以它是复制@answerid的值(因为那是只有属性可用)..你要做的是.. valu-of="."
..请尝试以下代码..
<xsl:template match="/XMLTest/result/*">
<answer>
<xsl:value-of select="local-name()"/>
</answer>
<xsl:if test="@answerid/.!=''">
<id>
<xsl:value-of select="@answerid"/>
</id>
</xsl:if>
<xsl:if test=".!=''">
<value>
<xsl:value-of select="."/>
</value>
</xsl:if>
</xsl:template>