1

我希望有人可以提供帮助,很可能是术语/方向。对 xslt 来说是全新的。我们有一堆文件有一些怪癖(不是很好的 xml)。我已经设法弄清楚属性、匹配和操作节点。我们有一个项目我不知道如何进行。单个节点包含一个逗号分隔的字符串。有一个条目(或一个或多个)(一个字符串),例如

 <what_transactions_are_included_overall>,,,datanormalnational,dataspecialnational,,,,,,,</what_transactions_are_included_overall>

下面是一组节点(不是孩子,同一级别)

<file>
 <planinfo>
   <plan_id>1</plan_id>
   <name>provider100_plan1</name>
   <what_transactions_are_included_overall>,,,datanormalnational,dataspecialnational,,,,,,,< /what_transactions_are_included_overall>
 </planinfo>

 <dataemailnational>
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
 </dataemailnational>
 <datanormalnational>
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
 </datanormalnational>
 <dataspecialnational>
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
 </dataspecialnational>
</file>

我已经匹配了孩子们以使其正常化并使用属性,所以我有这个

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:param name="pTransTypeDataEmail"/>
 <xsl:template match="node()|@*">
     <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>
  <xsl:template match="info">
     <info>
     <xsl:apply-templates select="@*|node()"/>
      <plan_id>plan.id</plan_id>
    </info>
 </xsl:template>

  <xsl:template match="data_email_national"> <transaction_type transaction_type="0"> <xsl:apply-templates select="@*|node()"/> </transaction_type> </xsl:template>
  <xsl:template match="data_normal_national"> <transaction_type transaction_type="1"> <xsl:apply-templates select="@*|node()"/> </transaction_type> </xsl:template>
  <xsl:template match="data_special_national"> <transaction_type transaction_type="2"> <xsl:apply-templates select="@*|node()"/> </transaction_type> </xsl:template>

这给了我

 <transactiontype transaction_type="0">
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
 </transactiontype>
 <transactiontype transaction_type="1">
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
 </transactiontype>
 <transactiontype transaction_type="2">
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
 </transactiontype>

我真的坚持尝试实现这一目标的方向:

     <transactiontype type="0">
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
   <transactions_included_overall>false</transactions_included_overall>   <!-- e.g. it was NOT in the csv list  -->
 </transactiontype>
<transactiontype type="1">
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
   <transactions_included_overall>true</transactions_included_overall>   <!-- e.g. it was in the csv list -->
 </transactiontype>
 <transactiontype type="2">
   <cost_included>-1</cost_included>
   <qty_included>-1</qty_included>
   <cost_per_transaction>0</cost_per_transaction>
   <transactions_included_overall>true</transactions_included_overall>  <!-- e.g. it was in the csv list -->
 </transactiontype>

我假设它是在顶部匹配模式的组合,不知道如何将其与下面的相关匹配进行协调?我应该先从字符串创建一个数组(我可以使用 2.0)还是只使用一个序列然后使用索引?...我感觉很接近,但不是 100% 确定。

感谢任何指导,谢谢

更新所以经过更多搜索后,我确定我到了那里,下载了 2.0 处理器(似乎 mac 的 xslt 只有 1.0)。有一些标记化工作,例如

 <xsl:template match="planfile/plan/planinfo/what_transactions_are_included_overall">
    <xsl:variable name="Tokens" select="tokenize(current(),',')"/>
     </xsl:template>

然后放一个

    <xsl:value-of select="$Tokens[1]"/>

在正确的地方。

但现在我遇到了一个问题,那就是它在不同的范围内。还要意识到变量并不是真正的变量,并且很难记住我 15 年前的函数式编程课程!我敢肯定我正在考虑程序上的工作,但我敢肯定......

4

1 回答 1

1

您可以通过将其放在任何模板之外来使其成为全局变量:

<xsl:variable name="Tokens" select="tokenize(
     /file/planinfo/what_transactions_are_included_overall,',')"/>

然后我会用一个模式定义另一对模板

<!-- for elements whose name is in the include list -->
<xsl:template mode="transactionIncluded"
              match="*[local-name() = $Tokens]">
  <transactions_included_overall>true</transactions_included_overall>
</xsl:template>

<!-- for elements whose name is *not* in the include list -->
<xsl:template mode="transactionIncluded"
              match="*">
  <transactions_included_overall>false</transactions_included_overall>
</xsl:template>

然后你可以在适当的地方使用这些模板

<xsl:template match="data_email_national">
  <transaction_type transaction_type="0">
    <xsl:apply-templates select="@*|node()"/>
    <xsl:apply-templates select="." mode="transactionIncluded" />
  </transaction_type>
</xsl:template>

编辑

从您的评论中:

我发现,<plan></plan>文件中不止一个,<planinfo>每个<plan>. [...] 我在想某种局部范围?

所以你有类似的东西

<file>
  <plan>
    <planinfo>
      <plan_id>1</plan_id>
      <name>provider100_plan1</name>
      <what_transactions_are_included_overall>,,,datanormalnational,,,,,,,,</what_transactions_are_included_overall>
    </planinfo>

    <datanormalnational>
      <cost_included>-1</cost_included>
      <qty_included>-1</qty_included>
      <cost_per_transaction>0</cost_per_transaction>
    </datanormalnational>
  </plan>
  <plan>
    <planinfo>
      <plan_id>1</plan_id>
      <name>provider100_plan1</name>
      <what_transactions_are_included_overall>,,,,dataspecialnational,,,,,,,</what_transactions_are_included_overall>
    </planinfo>
    <dataspecialnational>....</dataspecialnational>
  </plan>
</file>

你想要一个不同的集合what_transactions_are_included_overallplan?我认为您可以使用隧道参数机制对此进行攻击。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:param name="pTransTypeDataEmail"/>
 <xsl:template match="node()|@*">
     <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

  <xsl:template match="info">
     <info>
     <xsl:apply-templates select="@*|node()"/>
      <plan_id>plan.id</plan_id>
    </info>
 </xsl:template>

 <xsl:template match="plan">
   <!-- delegate to the normal identity template, but populate the tunnel
        parameter required by the transactionIncluded template -->
   <xsl:next-match>
     <xsl:with-param name="Tokens" tunnel="yes" select="tokenize(
       planinfo/what_transactions_are_included_overall,',')" />
   </xsl:next-match>
 </xsl:template>

 <xsl:template mode="transactionIncluded"
              match="*">
   <!-- use the Tokens parameter tunnelled in from the current <plan> -->
   <xsl:param name="Tokens" tunnel="yes" />
   <transactions_included_overall>
     <xsl:value-of select="if (local-name() = $Tokens) then 'true' else 'false'" />
   </transactions_included_overall>
 </xsl:template>

 <xsl:template match="data_email_national">
   <transaction_type transaction_type="0">
     <xsl:apply-templates select="@*|node()"/>
     <xsl:apply-templates select="." mode="transactionIncluded" />
   </transaction_type>
 </xsl:template>
 <!-- and similarly for the other transaction types -->

</xsl:stylesheet>

隧道参数会自动沿调用链向下传递,apply-template而无需在每个级别都使用显式xsl:param/ 。xsl:with-param

于 2013-07-17T10:56:29.933 回答