首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >XSL : XML到CSV转换,解析一个属性

XSL : XML到CSV转换,解析一个属性
EN

Stack Overflow用户
提问于 2018-05-02 15:06:17
回答 2查看 43关注 0票数 0

我在XSLT3.0中将XML文件转换为CSV文件,但只处理某些节点。其中一个节点是一个由空格分隔的多个值的属性,我希望在目标CSV文件中将每个值分解为一个单独的行。

示例源XML文件:

代码语言:javascript
运行
复制
<corpus>
 <deposition>
    <deposition-number n="dep1"/>
    <text>
      <seg n="seg1">Lorem ipsum dolor sit amet, <persName name="personA" ana="foo1 foo2">some foo person</persName> 
        adipiscing elit. Vivamu ultrices consequat facilisis. 
        Suspendisse a odio in lobortis. Aenean <persName name="personG" ana="foo2">some foo person</persName>
        non dui scelerisque, rutrum est at, cursus sem.</seg>
      <seg n="seg2">Ut pharetra <persName name="personF" ana="foo9">some foo person</persName>bibendum ipsum, portitor 
        velit pharetra quis. Aeneano purus. Praesent 
        aliquam viverra tellus.</seg>
     </text>
  </deposition>
  <deposition>
    <deposition-number n=""dep2"/>
    <text>
     <seg n="seg3">Curabitur pulvinar leo eget. Orci varius 
        natoque penatibus et magnis <persName name="personD" ana="foo2 foo3 foo8">some foo person</persName>montes, 
        nascetur ridiculus mus.</seg>
    </text>
  </deposition>
</corpus>

目前,我可以在CSV中输出这个不满意的结果,其中@ana位于最后一个字段:

代码语言:javascript
运行
复制
 dep1~seg1~personA~foo1 foo2
 dep1~seg1~personG~foo2
 dep1~seg2~personF~foo9
 dep1~seg3~personD~foo2 foo3 foo8

对于XSL,如下所示:

代码语言:javascript
运行
复制
<xsl:template match="/">
    <xsl:for-each select="persName">
        <xsl:value-of select="ancestor::deposition-number/@n"/>
        <xsl:text>~</xsl:text>
        <xsl:value-of select="ancestor::seg/@n"/>
        <xsl:text>~</xsl:text>
        <xsl:value-of select="@name"/>
        <xsl:text>~</xsl:text>
        <xsl:value-of select="@ana"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

但是我想输出这个,其中@ana被解析成不同的行:

代码语言:javascript
运行
复制
 dep1~seg1~personA~foo1
 dep1~seg1~personA~foo2
 dep1~seg1~personG~foo2
 dep1~seg2~personF~foo9
 dep1~seg3~personD~foo2
 dep1~seg3~personD~foo3
 dep1~seg3~personD~foo8

我曾经尝试过标记化,但是如果它能够解决这个问题,我不知道如何去做。我不知道如何解析@ana并遍历它。

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-02 15:13:46

尝试这个模板,它使用tokenize来分割属性,并为每个值输出一行

代码语言:javascript
运行
复制
<xsl:template match="/">
    <xsl:for-each select="//persName">
        <xsl:variable name="pers" select="." />
        <xsl:for-each select="tokenize(@ana, ' ')">
            <xsl:value-of select="$pers/ancestor::deposition/deposition-number/@n"/>
            <xsl:text>~</xsl:text>
            <xsl:value-of select="$pers/ancestor::seg/@n"/>
            <xsl:text>~</xsl:text>
            <xsl:value-of select="$pers/@name"/>
            <xsl:text>~</xsl:text>
            <xsl:value-of select="."/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

(请注意,deposition-number不是XML中persName的祖先)

或者,简化一下,试试这个.

代码语言:javascript
运行
复制
<xsl:template match="/">
    <xsl:for-each select="//persName">
        <xsl:variable name="pers" select="." />
        <xsl:for-each select="tokenize(@ana, ' ')">
            <xsl:value-of select="($pers/ancestor::deposition/deposition-number/@n, $pers/ancestor::seg/@n, $pers/@name, .)" separator="~"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>
票数 3
EN

Stack Overflow用户

发布于 2018-05-02 15:22:17

使用XSLT 3,您可以标记值并将它们推送到模板中:

代码语言:javascript
运行
复制
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="3.0">

  <xsl:output method="text"/>

  <xsl:template match="/">
      <xsl:apply-templates select="//persName"/>
  </xsl:template>

  <xsl:template match="persName">
     <xsl:apply-templates select="tokenize(@ana, '\s+')">
         <xsl:with-param name="data" select="ancestor::deposition/deposition-number/@n, ancestor::seg/@n, @name"/>
     </xsl:apply-templates>
  </xsl:template>

  <xsl:template match=".[. instance of xs:string]">
      <xsl:param name="data"/>
      <xsl:value-of select="$data, ." separator="~"/>
      <xsl:text>&#10;</xsl:text>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bdxtpS/1

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50137863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档