XML到CSV只能检索动态属性



根据我之前的问题。

我们更改了XML结构,因此输入现在看起来像这样:

<EXPORT>
  <DOCUMENTS>
    <DOCUMENT>
      <INDEX NAME="NAME" VALUE="folder"/>
      <INDEX NAME="LOCATION" VALUE="C:here"/>
    </DOCUMENT>
    <DOCUMENT>
      <INDEX NAME="COLOR" VALUE="blue"/>
      <INDEX NAME="LOCATION" VALUE="C:here"/>
      <INDEX NAME="DATE" VALUE="01-25-2015"/>
    </DOCUMENT>
  </DOCUMENTS>
</EXPORT>

对于本例,我希望得到以下CSV输出:

NAME,LOCATION,COLOR,DATE
folder, c:here,,
,C:here,blue,01-25-2015

我痛苦地尝试了很多东西,但我不知道generate-id是如何工作的。最后我得到了这个完全不能工作的XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:variable name="delimiter" select="','"/>
  <xsl:key name="fields" match="/EXPORT/DOCUMENTS/*" use="./@name"/>
  <xsl:variable name="Fields"
       select="/EXPORT/DOCUMENTS/*[generate-id()=generate-id(key('fields', local-name())[1])]" />
  <xsl:template match="/">
    <xsl:for-each select="$Fields">
      <xsl:value-of select="local-name()" />
      <xsl:if test="position() &lt; last()">
        <xsl:value-of select="$delimiter" />
      </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="*/*" />
  </xsl:template>
  <xsl:template match="*">
    <xsl:variable name="this" select="." />
    <xsl:for-each select="$Fields">
      <xsl:value-of select="$this/*[local-name() = local-name(current())]" />
      <xsl:if test="position() &lt; last()">
        <xsl:value-of select="$delimiter" />
      </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

我应该改变什么?你有更好的方法吗?

你的第一个问题是与键

 <xsl:key name="fields" match="/EXPORT/DOCUMENTS/*" use="./@name"/>

这只是得到DOCUMENT元素,当你真正想要INDEX元素。而且,它区分大小写,所以属性是@NAME而不是@name

<xsl:key name="fields" match="/EXPORT/DOCUMENTS/DOCUMENT/*" use="@NAME"/>

然而,当您开始使用键时,您经常使用local-name(),但这会获取元素的名称(在本例中,始终是INDEX),因此您需要将所有出现的local-name()替换为获取NAME属性。

例如:

<xsl:variable name="Fields"
   select="/EXPORT/DOCUMENTS/DOCUMENT/*[generate-id()=generate-id(key('fields', @NAME)[1])]" />

还要注意,当您输出字段值时,您希望输出VALUE属性的值,而不是元素本身的实际文本值

<xsl:value-of select="$this/*[@NAME = $name]/@VALUE" />

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:variable name="delimiter" select="','"/>
  <xsl:key name="fields" match="/EXPORT/DOCUMENTS/DOCUMENT/*" use="./@NAME"/>
  <xsl:variable name="Fields"
       select="/EXPORT/DOCUMENTS/DOCUMENT/*[generate-id()=generate-id(key('fields', @NAME)[1])]" />
  <xsl:template match="/">
    <xsl:for-each select="$Fields">
      <xsl:value-of select="@NAME" />
      <xsl:if test="position() &lt; last()">
        <xsl:value-of select="$delimiter" />
      </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="*/*/*" />
  </xsl:template>
  <xsl:template match="*">
    <xsl:variable name="this" select="." />
    <xsl:for-each select="$Fields">
      <xsl:variable name="name" select="@NAME" />
      <xsl:value-of select="$this/*[@NAME = $name]/@VALUE" />
      <xsl:if test="position() &lt; last()">
        <xsl:value-of select="$delimiter" />
      </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

相关内容

  • 没有找到相关文章

最新更新