2

如果parent_item列中的值在 CSV 文件中出现超过 1 次,我需要评估 CSV 文件的每一行。我需要将布尔值输出到新列 - 让我们标记它parent_count。如果 parent_item 列中的值在 CSV 文件中出现 2 次或更多次,则向 parent_count 输出 TRUE,否则向 parent_count 字段输出 FALSE。如果可以使用 XSLT 中的代码来完成,有人可以帮助我吗?

文件将从 XML 转换为 CSV。

请帮助,因为我是 XSLT 的新手。

编辑

<AdditionalAttributes groupLabel="Custom Attributes">
    <AdditionalAttribute dataType="Decimal" value="" name="Standard Cost" dimension="$"/>
    <AdditionalAttribute dataType="Decimal" value="" name="Target Cost" dimension="$"/>
    <AdditionalAttribute dataType="Decimal" value="" name="Target Price" dimension="$"/>
    <AdditionalAttribute description="quoted" dataType="Decimal" value="" name="Active Cost #1" dimension="$"/>
    <AdditionalAttribute description="quoted" dataType="Decimal" value="" name="Active Cost #2" dimension="$"/>
    <AdditionalAttribute dataType="String" value="" name="Active Cost Line #1"/>
    <AdditionalAttribute dataType="String" value="" name="Active Cost Line #2"/>
    <AdditionalAttribute dataType="String" value="" name="Description"/>
    <AdditionalAttribute dataType="String" value="Off-the-Shelf (OTS)" name="Procurement Type"/>
    <AdditionalAttribute dataType="String" value="OTHER" name="General Posting Group"/>
    <AdditionalAttribute dataType="String" value="OTHER" name="Inventory Posting Group"/>
    <AdditionalAttribute dataType="String" value="PARTS" name="Item Category Group"/>
</AdditionalAttributes>

编辑要求

我有一列parent_item,其中的值是这样的

  • parent_item parent_count

    1. 第 1 行:441-0230-001 真

    2. 第 2 行:441-0230-001 真

    3. 第 3 行:441-0230-001 真

    4. 第 4 行:441-0230-001 是的

    5. 第 5 行:SP-SSD-80GB 错误

现在第 1 行中的值对 4 条记录重复 4 次,因此 parent_count 中的值是 true。并且父项中的第 5 行值仅出现一次。因此父项计数为 false。

这是我的确切要求。你能帮我实现吗?我对 XSL 编码很陌生。

新的 XML

<Item
   itemIdentifier="650-0107-001"
   itemUniqueIdentifier="IVI10144102348"
   globalLifeCyclePhaseCode="Production"
   globalProductTypeCode="6xx - PCBA&apos;s"
   revisionIdentifier="A"
   proprietaryProductFamily=""
   category="6xx - PCBA&apos;s"
   globalProductUnitOfMeasureCode="FA"
   revisionReleasedDate="2013-07-31T00:00:00-08:00"
   ownerName=""
   isTopLevel="Yes"
   description="Transceivers">

  <AdditionalAttributes groupLabel="Version Information">
    <AdditionalAttribute name="Version Notes" value="test" dataType="String"></AdditionalAttribute>
    <AdditionalAttribute name="Change Number" value="DEV-000130" dataType="String"></AdditionalAttribute>
    <AdditionalAttribute name="Version Shared" value="Yes" dataType="String"></AdditionalAttribute>
    <AdditionalAttribute name="Effective Version Shared" value="Yes" dataType="String"></AdditionalAttribute>
    <AdditionalAttribute name="Material Effectivity Date" value="2013-05-20T11:05:41-08:00" dataType="String"></AdditionalAttribute>
    <AdditionalAttribute name="Disposition Notes" value="In the Field =N/A- Does Not Apply; WIP =N/A-Does Not Apply; On Order =N/A-Does Not Apply; Finished Goods =N/A-Does Not Apply; In Stock =See Notes; In Stock Notes=Authorize existing stock until specified expiration 7/31/2013; Depot =N/A- Does Not Apply; CTO-Configure to Order =N/A-Does Not Apply" dataType="String"></AdditionalAttribute>
    <AdditionalAttribute name="Item Creation Date" value="2012-07-06T12:14:03-08:00" dataType="String"></AdditionalAttribute>
  </AdditionalAttributes>
</Item>

XSLT 代码

这是我添加列的代码

<map:attribute type="internal" ref="id" container="Item">
    <map:aren>itemIdentifier</map:aren>
    <map:generic delimiter="false" name="parent_item" width="50"/>
</map:attribute>
4

1 回答 1

2

如果数据的源格式是 XML,这绝对可以使用 XSLT 完成。您可以遍历代表未来 CSV 文件中一行的标记,然后使用带有 count 的 xpath 表达式进行所需的测试。

根据您的输入,我将假设我们有以下(为简洁起见)输入文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Items>
  <Item
      itemIdentifier="650-0107-001"
      itemUniqueIdentifier="IVI99999999999"
      description="Transceivers">
    <AdditionalAttributes groupLabel="Custom Attributes">
      <AdditionalAttribute dataType="String" value="OTHER1" name="Inventory Posting Group"/>
      <AdditionalAttribute dataType="String" value="PARTS1" name="Item Category Group"/>
    </AdditionalAttributes>
  </Item>
  <Item
      itemIdentifier="650-0107-001"
      itemUniqueIdentifier="IVI10144102348"
      description="Receivers">
    <AdditionalAttributes groupLabel="Custom Attributes">
      <AdditionalAttribute dataType="String" value="OTHER2" name="Inventory Posting Group"/>
      <AdditionalAttribute dataType="String" value="PARTS2" name="Item Category Group"/>
    </AdditionalAttributes>
  </Item>
  <Item
      itemIdentifier="SP-SSD-80GB"
      itemUniqueIdentifier="IVI10144102348"
      description="Transmitters">
    <AdditionalAttributes groupLabel="Custom Attributes">
      <AdditionalAttribute dataType="String" value="OTHER3" name="Inventory Posting Group"/>
      <AdditionalAttribute dataType="String" value="PARTS3" name="Item Category Group"/>
    </AdditionalAttributes>
  </Item>
</Items>

此外,我们还有一些小的映射文件,它们定义了parent_item

<?xml version="1.0" encoding="ISO-8859-1" ?>
<maps xmlns:map="http://my.namespace">
  <map:attribute 
      type="internal" ref="id" container="Item">
    <map:aren>itemIdentifier</map:aren>
    <map:generic delimiter="false" name="parent_item" width="50"/>
  </map:attribute>
</maps>

使用简单版本的反射( local-name())(请参阅Get tag name/attribute name in XML using XSLT)以下 XSLT 表

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet 
    version="1.0"
    xmlns:map="http://my.namespace"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="map_name"/>
  <xsl:variable name="map" select="document($map_name)"/>

  <xsl:output method="text"/>

  <xsl:template match="/Items">

    <xsl:for-each select="Item">

      <xsl:for-each select="@*">

        <!-- output the attribute value -->
        <xsl:value-of select="."/><xsl:text>;</xsl:text>
        <!-- get the name of parent_item attribute from the map -->
        <xsl:variable name="parent_item" select="$map/maps/map:attribute/map:aren/text()"/>

        <!-- if the current attribute is a parent_item execute the uniqueness check -->
        <xsl:if test="$map/maps/map:attribute/map:aren = local-name(.)">

          <!-- introduce local variable for easy test below-->
          <xsl:variable name="current_parent_value" select="../@*[local-name(.) = $parent_item]"/>
          <!-- compute the boolean column depending on the count of current_parent_item -->
          <xsl:variable name="parent_count">

            <xsl:choose>
              <!-- note that we have to compare > 1 (and not > 0) since an entry will ALWAYS find itself -->
              <xsl:when test="count(/Items/Item[ @*[local-name(.) = $parent_item] = $current_parent_value]) > 1">
                <xsl:text>TRUE</xsl:text>
              </xsl:when>
              <xsl:otherwise>
                <xsl:text>FALSE</xsl:text>            
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <!-- output the result of the uniqueness check -->
          <xsl:value-of select="$parent_count"/><xsl:text>;</xsl:text>

        </xsl:if>

      </xsl:for-each>

      <xsl:for-each select="AdditionalAttributes/AdditionalAttribute">
        <!-- output the values of the remaining attributes -->
        <xsl:value-of select="@value"/><xsl:text>;</xsl:text>
      </xsl:for-each>

      <xsl:text>&#10;</xsl:text>

    </xsl:for-each>

  </xsl:template>
</xsl:stylesheet>

将生成 CSV 结果文件

650-0107-001;TRUE;IVI99999999999;Transceivers;OTHER1;PARTS1;
650-0107-001;TRUE;IVI10144102348;Receivers;OTHER2;PARTS2;
SP-SSD-80GB;FALSE;IVI10144102348;Transmitters;OTHER3;PARTS3;

如果我们使用不同的地图文件

<?xml version="1.0" encoding="ISO-8859-1" ?>
<maps xmlns:map="http://my.namespace">
  <map:attribute 
      type="internal" ref="id" container="Item">
    <map:aren>itemUniqueIdentifier</map:aren>
    <map:generic delimiter="false" name="parent_item" width="50"/>
  </map:attribute>
</maps>

我们会得到这个结果:

650-0107-001;IVI99999999999;FALSE;Transceivers;OTHER1;PARTS1;
650-0107-001;IVI10144102348;TRUE;Receivers;OTHER2;PARTS2;
SP-SSD-80GB;IVI10144102348;TRUE;Transmitters;OTHER3;PARTS3;

笔记:

  • 映射文件的名称作为参数传递map_name。您必须了解这对您的处理器是如何工作的。如果xlstproc您必须使用 xsltproc --stringparam map_name "map.xml" convert.xslt input.xml > output.csv
  • 代码仍然对 所在的标签做出假设parent_item。原则上,您可以通过遍历文档以匹配标签来使其更加通用,但我不认为您需要这个。
  • 从地图文件中提取名称的过程parent_item相当简单。如果适用,您可能需要添加额外的过滤。
  • 当然,您必须根据需要微调输出。迭代输出属性的通用方法只是一个示例。
  • 这对我来说是一项有趣的任务,因为这是我第一次在 XLS 中使用反射。:-)
于 2013-10-20T13:16:29.363 回答