Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
xml获取参数值并输出到csv_Xml_Xslt - Fatal编程技术网

xml获取参数值并输出到csv

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">

我有以下xml结构

<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>&#13;&#10;</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('&#x9;',1 div not($vValue)),$vValue)"/>
        </xsl:for-each>
        <xsl:text>&#xA;</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>&#x9;</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>&#x9;,&#x9;</xsl:text>
        </xsl:if>
        <xsl:value-of select="concat(
                                 ',',
                                 (color/@titel|color/text())[last()],
                                 '&#xA;'
                              )"/>
    </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('&#x9;',1 div not($vValue)),$vValue)"/>
        </xsl:for-each>
        <xsl:text>&#xA;</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>&#x9;</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>&#x9;,&#x9;</xsl:text>
        </xsl:if>
        <xsl:value-of select="concat(
                                 ',',
                                 (color/@titel|color/text())[last()],
                                 '&#xA;'
                              )"/>
    </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('&#x9;',1 div not($vValue)),$vValue)"/>
        </xsl:for-each>
        <xsl:text>&#xA;</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>&#x9;</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>&#x9;,&#x9;</xsl:text>
        </xsl:if>
        <xsl:value-of select="concat(
                                 ',',
                                 (color/@titel|color/text())[last()],
                                 '&#xA;'
                              )"/>
    </xsl:template>
</xsl:stylesheet>
car,volvo,red
    ,   ,green
    ,ford,red
bike,trek,blue