xml获取参数值并输出到csv
我有以下xml结构xml获取参数值并输出到csv,xml,xslt,Xml,Xslt,我有以下xml结构 <transport titel="vervoer"> <type titel="car"> <brand titel="volvo"> <color titel="kleur">red</color> </brand> </type> <type titel="car"> <brand titel="volvo">
<transport titel="vervoer">
<type titel="car">
<brand titel="volvo">
<color titel="kleur">red</color>
</brand>
</type>
<type titel="car">
<brand titel="volvo">
<color titel="kleur">green</color>
</brand>
</type>
<type titel="car">
<brand titel="ford">
<color titel="kleur">red</color>
</brand>
</type>
<type titel="bike">
<brand titel="trek">
<color titel="kleur">blue</color>
</brand>
</type>
</transport>
但是这种方法有两个问题1.有没有一种方法可以从树的顶端走到树的顶端,并在可用时显示所有滴度?如果存在没有颜色子节点的节点,则不会显示该节点
<type titel="bike">
<brand titel="trek">
</brand>
</type>
您的问题是在
中为每个选择
,因此您将错过每个没有
子代的
对每个
使用处理的替代方法可以是:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" />
<xsl:strip-space elements="transport" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="transport">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="type">
<xsl:choose>
<xsl:when test="@titel">
<xsl:value-of select="@titel" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="' '" />
</xsl:otherwise>
</xsl:choose>
<xsl:text>,</xsl:text>
<xsl:choose>
<xsl:when test="brand[@titel]">
<xsl:apply-templates select="brand" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="' '" />
</xsl:otherwise>
</xsl:choose>
<xsl:text>,</xsl:text>
<xsl:choose>
<xsl:when test="brand/color">
<xsl:apply-templates select="brand/color" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="' '" />
</xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="brand">
<xsl:value-of select="@titel"/>
</xsl:template>
<xsl:template match="brand/color">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
要从输出中省略不需要的元素,只需添加一个空模板:
...
<xsl:template match="sometext" />
</xsl:stylesheet>
。。。
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kElementByName" match="*/*" use="name()"/>
<xsl:variable name="vFields"
select="//*/*[count(.|key('kElementByName',name())[1])=1]"/>
<xsl:template match="/*/*">
<xsl:variable name="vCurrent" select="."/>
<xsl:for-each select="$vFields">
<xsl:variable name="vField"
select="$vCurrent/descendant-or-self::*[
name() = name(current())
]"/>
<xsl:variable name="vValue"
select="($vField/@titel|$vField/text())[last()]"/>
<xsl:if test="position()!=1">,</xsl:if>
<xsl:value-of
select="concat(substring('	',1 div not($vValue)),$vValue)"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kTypeByTitel" match="type" use="@titel"/>
<xsl:key name="kBrandByType-Titel" match="brand"
use="concat(../@titel,'++',@titel)"/>
<xsl:template match="/*">
<xsl:apply-templates
select="type[count(.|key('kTypeByTitel',@titel)[1])=1]"/>
</xsl:template>
<xsl:template match="type">
<xsl:value-of select="@titel"/>
<xsl:apply-templates
select="key('kTypeByTitel',@titel)/brand[
count(.|key('kBrandByType-Titel',
concat(../@titel,'++',@titel)
)[1]
) = 1
]"/>
</xsl:template>
<xsl:template match="brand">
<xsl:if test="position()!=1">
<xsl:text>	</xsl:text>
</xsl:if>
<xsl:value-of select="concat(',',@titel)"/>
<xsl:apply-templates select="key('kBrandByType-Titel',
concat(../@titel,'++',@titel)
)"
mode="color"/>
</xsl:template>
<xsl:template match="brand" mode="color">
<xsl:if test="position()!=1">
<xsl:text>	,	</xsl:text>
</xsl:if>
<xsl:value-of select="concat(
',',
(color/@titel|color/text())[last()],
'
'
)"/>
</xsl:template>
</xsl:stylesheet>
编辑:按注释请求分组,此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kElementByName" match="*/*" use="name()"/>
<xsl:variable name="vFields"
select="//*/*[count(.|key('kElementByName',name())[1])=1]"/>
<xsl:template match="/*/*">
<xsl:variable name="vCurrent" select="."/>
<xsl:for-each select="$vFields">
<xsl:variable name="vField"
select="$vCurrent/descendant-or-self::*[
name() = name(current())
]"/>
<xsl:variable name="vValue"
select="($vField/@titel|$vField/text())[last()]"/>
<xsl:if test="position()!=1">,</xsl:if>
<xsl:value-of
select="concat(substring('	',1 div not($vValue)),$vValue)"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kTypeByTitel" match="type" use="@titel"/>
<xsl:key name="kBrandByType-Titel" match="brand"
use="concat(../@titel,'++',@titel)"/>
<xsl:template match="/*">
<xsl:apply-templates
select="type[count(.|key('kTypeByTitel',@titel)[1])=1]"/>
</xsl:template>
<xsl:template match="type">
<xsl:value-of select="@titel"/>
<xsl:apply-templates
select="key('kTypeByTitel',@titel)/brand[
count(.|key('kBrandByType-Titel',
concat(../@titel,'++',@titel)
)[1]
) = 1
]"/>
</xsl:template>
<xsl:template match="brand">
<xsl:if test="position()!=1">
<xsl:text>	</xsl:text>
</xsl:if>
<xsl:value-of select="concat(',',@titel)"/>
<xsl:apply-templates select="key('kBrandByType-Titel',
concat(../@titel,'++',@titel)
)"
mode="color"/>
</xsl:template>
<xsl:template match="brand" mode="color">
<xsl:if test="position()!=1">
<xsl:text>	,	</xsl:text>
</xsl:if>
<xsl:value-of select="concat(
',',
(color/@titel|color/text())[last()],
'
'
)"/>
</xsl:template>
</xsl:stylesheet>
注意:不需要有序的输入源。固定字段,因为一般解决方案(按动态键嵌套分组)是XSLT 1.0中最复杂的任务请参阅我的更新答案,了解您的空格填充字段要求。它似乎不适用于我的xml文件?我现在有很多空行,所需的行没有被newline?@user664191正确终止。提供的Xslt仅适用于示例的Xml文档结构。如果实际的Xml文档具有不同的结构,则可能需要相应地采用Xslt模板结构。此外,还需要将要从输出中排除的元素添加到strip space
指令(位于Xslt样式表的顶部)。输出中的空行表示情况就是这样。更新您的Xml输入示例,我将更新我的Xslt代码以适应示例中的.thx,但我需要在输出中有一些规则:当前一个元素相同时,它应该有一个空格或空值:car、volvo、red、green car、ford、green
此外,节点周围还有大量额外的文本,所以我需要把它过滤到元素specified@user664191:您应该将此添加到您的问题中。
...
<xsl:template match="sometext" />
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kElementByName" match="*/*" use="name()"/>
<xsl:variable name="vFields"
select="//*/*[count(.|key('kElementByName',name())[1])=1]"/>
<xsl:template match="/*/*">
<xsl:variable name="vCurrent" select="."/>
<xsl:for-each select="$vFields">
<xsl:variable name="vField"
select="$vCurrent/descendant-or-self::*[
name() = name(current())
]"/>
<xsl:variable name="vValue"
select="($vField/@titel|$vField/text())[last()]"/>
<xsl:if test="position()!=1">,</xsl:if>
<xsl:value-of
select="concat(substring('	',1 div not($vValue)),$vValue)"/>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
car,volvo,red
car,volvo,green
car,ford,red
bike,trek,blue
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kTypeByTitel" match="type" use="@titel"/>
<xsl:key name="kBrandByType-Titel" match="brand"
use="concat(../@titel,'++',@titel)"/>
<xsl:template match="/*">
<xsl:apply-templates
select="type[count(.|key('kTypeByTitel',@titel)[1])=1]"/>
</xsl:template>
<xsl:template match="type">
<xsl:value-of select="@titel"/>
<xsl:apply-templates
select="key('kTypeByTitel',@titel)/brand[
count(.|key('kBrandByType-Titel',
concat(../@titel,'++',@titel)
)[1]
) = 1
]"/>
</xsl:template>
<xsl:template match="brand">
<xsl:if test="position()!=1">
<xsl:text>	</xsl:text>
</xsl:if>
<xsl:value-of select="concat(',',@titel)"/>
<xsl:apply-templates select="key('kBrandByType-Titel',
concat(../@titel,'++',@titel)
)"
mode="color"/>
</xsl:template>
<xsl:template match="brand" mode="color">
<xsl:if test="position()!=1">
<xsl:text>	,	</xsl:text>
</xsl:if>
<xsl:value-of select="concat(
',',
(color/@titel|color/text())[last()],
'
'
)"/>
</xsl:template>
</xsl:stylesheet>
car,volvo,red
, ,green
,ford,red
bike,trek,blue