Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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
Arrays 如何在XSLT中处理不同循环中的数组_Arrays_Xslt_Xsl Variable - Fatal编程技术网

Arrays 如何在XSLT中处理不同循环中的数组

Arrays 如何在XSLT中处理不同循环中的数组,arrays,xslt,xsl-variable,Arrays,Xslt,Xsl Variable,我在处理以下xml代码时遇到问题: <?xml version="1.0" encoding="UTF-8"?> <searchresult> <head> <heading> <title>Column1</title> <dataType>TEXT</dataType> </heading> <heading>

我在处理以下xml代码时遇到问题:

<?xml version="1.0" encoding="UTF-8"?>
<searchresult>
  <head>
    <heading>
      <title>Column1</title>
      <dataType>TEXT</dataType>
    </heading>
    <heading>
      <title>Column2</title>
      <dataType>DATE</dataType>
      <dataFormat>SHORT_DATE</dataFormat>
    </heading>
  </head>
  <data>
    <row>
      <column>
        <value>Hello</value>
      <column>
      <column>
        <value>2012-07-12</value>
      <column>
    </row>
    <row>
      <column>
        <value>Good bye</value>
      <column>
      <column>
        <value>2012-07-13</value>
      <column>
    </row>
  </data>
</searchresult>

专栏1
正文
专栏2
日期
短期约会
你好
2012-07-12
再见
2012-07-13
我需要将此xml转换为EXCEL兼容文件(我使用urn:schemas microsoft com:office:office、urn:schemas microsoft com:office:EXCEL和urn:schemas microsoft com:office:spreadsheet命名空间)

问题是我不知道如何在行/列/值上应用head/heading元素dataType+dataFormat(如果可用)中的信息。这将有助于Excel识别单元格中的数据类型。 很明显,我需要保持秩序。列数及其元数据是动态的,每个XML可能不同

我需要这样的东西:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Workbook --several namespaces here-->

<Worksheet ss:Name="SearchResult">
  <Table x:FullRows="1" x:FullColumns="1">
    <Row ss:Height="12.75">
      <Cell>
        <Data ss:Type="String">Column1</Data>
      </Cell>
      <Cell>
        <Data ss:Type="String">Column2</Data>
      </Cell>
    </Row>
    <Row ss:Height="12.75">
      <Cell>
        <Data ss:Type="String">Hello : TEXT</Data>
      </Cell>
      <Cell>
        <Data ss:Type="Date">2012-07-12 : DATE - SHORT_DATE</Data>
      </Cell>
    </Row>
    <Row ss:Height="12.75">
      <Cell>
        <Data ss:Type="String">Good bye : TEXT</Data>
      </Cell>
      <Cell>
        <Data ss:Type="Date">2012-07-12 : DATE - SHORT_DATE</Data>
      </Cell>
    </Row>
  </Table>
</Worksheet>    
</Workbook>

专栏1
专栏2
你好:文本
2012-07-12:日期-短日期
再见:文本
2012-07-12:日期-短日期
我尝试过几次创造一些有用且有效的东西,但我所有的尝试都失败了。当前版本如下:

  <xsl:template match="searchresult">
    <Worksheet>
      --some unimportant script--
      <Table x:FullColumns="1" x:FullRows="1">
        <xsl:apply-templates select="head" />
        <xsl:apply-templates select="elements/row"/>
      </Table>
    </Worksheet>
  </xsl:template>

  <xsl:template match="head">       
    <Row>
      <xsl:for-each select="*">
        <!-- resolve data-type and remember it as variable -->
        <xsl:variable name="concat('dataType', position())" select="dataType">
          <xsl:choose>
            <xsl:when test="TEXT">
              <xsl:value-of select=".">String</xsl:value-of>
            </xsl:when>
            <xsl:when test="DATE">
              <xsl:value-of select=".">DateTime</xsl:value-of>
            </xsl:when>
          </xsl:choose>
        </xsl:variable>
        <xsl:variable name="concat('dataFormat', position())" select="dataFormatter" >
          <!-- create style IDs for different formats -->
        </xsl:variable>
        <Cell>
          <Data ss:Type="String">
            <xsl:value-of select="title/." />
          </Data>
        </Cell>
      </xsl:for-each>
    </Row>              
  </xsl:template>

  <xsl:template match="elements/row/column">
    <xsl:for-each select="values">
      <Cell>
        <!-- resolve order within loop and pick correct data-type variable -->
        <xsl:variable name="type" select="concat('$dataType', position())" />
        <xsl:variable name="format" select="concat('$dataFormat', position())" />
        <Data ss:Type="$type">
          <xsl:value-of select="concat(normalize-space(.),' : ', $type)"/>
          <!-- check if data format is set -->
          <xsl:if test="//TODO">
            <xsl:value-of select="concat(' - ', $format)" />
          </xsl:if>
        </Data>
      </Cell>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

--一些不重要的剧本--
一串
日期时间
这个版本是无用的,因为我不能使用任何变量值作为变量名,它必须是常量值。解析整个数据在某种程度上是有效的,但当我试图实现数据类型和数据格式时,它就崩溃了

编辑:有关数据类型和数据格式的信息放置在head元素中,该元素保存有关列及其标题的所有信息。 列在单独的模板中处理,并且它们不直接连接到head元素中的列定义。关系仅通过元素的顺序来维护。
我需要处理每行和每个单元格(适当列)的数据类型和可能的数据格式(可选)信息,而不仅仅是标题。

您可以使用键按位置查找标题元素

<xsl:key name="headings" match="heading" use="count(preceding-sibling::heading)" />

然后,假设您位于元素上,您将根据位置获得关联的数据类型,如下所示

<xsl:variable 
   name="dataType" 
   select="key('headings', count(preceding-sibling::column))/dataType" /> 

i、 e对于行中的第一个元素,您将查找第一个标题元素,并获取数据类型

关于XSLT,还需要注意其他一些事情。首先,不允许使用动态变量名称,如以下所示

<xsl:variable name="concat('dataType', position())" select="dataType"> 

如果使用select属性,也不允许在变量中包含非空内容

其次,如果要在输出属性中使用变量值,则需要使用属性值模板。而不是这样做

<Data ss:Type="$type">

你会这么做的

<Data ss:Type="{$type}">

此外,您应该支持xsl:apply模板,而不是xsl:for each,因为它们鼓励代码重用,减少嵌套代码,并且更符合XSLT的精神

无论如何,这里是完整的XSLT(注意使用了组合的名称空间)


一串
日期
当应用于示例XML时,将输出以下内容

<Worksheet xmlns:x="x" xmlns:ss="ss">
   <Table x:FullColumns="1" x:FullRows="1">
      <Row>
         <Cell>
            <Data ss:Type="String">Column1</Data>
         </Cell>
         <Cell>
            <Data ss:Type="String">Column2</Data>
         </Cell>
      </Row>
      <row>
         <Cell>
            <Data ss:Type="String">Hello : String</Data>
         </Cell>
         <Cell>
            <Data ss:Type="Date">2012-07-12 : Date - SHORT_DATE</Data>
         </Cell>
      </row>
      <row>
         <Cell>
            <Data ss:Type="String">Good bye : String</Data>
         </Cell>
         <Cell>
            <Data ss:Type="Date">2012-07-13 : Date - SHORT_DATE</Data>
         </Cell>
      </row>
   </Table>
</Worksheet>

专栏1
专栏2
你好:字符串
2012-07-12:日期-短日期
再见:弦
2012-07-13:日期-短日期

您可以使用键按位置查找标题元素

<xsl:key name="headings" match="heading" use="count(preceding-sibling::heading)" />

然后,假设您位于元素上,您将根据位置获得关联的数据类型,如下所示

<xsl:variable 
   name="dataType" 
   select="key('headings', count(preceding-sibling::column))/dataType" /> 

i、 e对于行中的第一个元素,您将查找第一个标题元素,并获取数据类型

关于XSLT,还需要注意其他一些事情。首先,不允许使用动态变量名称,如以下所示

<xsl:variable name="concat('dataType', position())" select="dataType"> 

如果使用select属性,也不允许在变量中包含非空内容

其次,如果要在输出属性中使用变量值,则需要使用属性值模板。而不是这样做

<Data ss:Type="$type">

你会这么做的

<Data ss:Type="{$type}">

此外,您应该支持xsl:apply模板,而不是xsl:for each,因为它们鼓励代码重用,减少嵌套代码,并且更符合XSLT的精神

无论如何,这里是完整的XSLT(注意使用了组合的名称空间)