XSLT条件模板转换

时间:2015-04-15 04:31:20

标签: c# xml templates datetime xslt

我有一个XMl,我想根据条件删除它的一部分。 XML如下:

<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Header>
      <MessageID>0a9d3ba5-9025-4e24-a0de-2403a0c0919b</MessageID>
      <MessageDate>2015-04-10</MessageDate>
      <PPMVersion>6.0.0.0</PPMVersion>
      <SchemaVersion>1.0</SchemaVersion>
   </Header>
   <Package xsi:type="Ritter_Sales_Template" Path="/Package/Product/Launch_Entity" BusinessID="010170" ID="a13b6861-bb32-47fa-8ef4-f0ddcc0bc134">
      <Name>MOTO_pack</Name>
      <Category_ID Product_Line_ID="5">5</Category_ID>
      <Effective_Start_Date>2015-02-23</Effective_Start_Date>
      <Available_Start_Date>2015-02-23</Available_Start_Date>
      <Element_Guid>a13b6861-bb32-47fa-8ef4-f0ddcc0bc134</Element_Guid>
      <Element_Type_Guid>f7e69de1-23e8-4a66-b57b-d849e989e1ce</Element_Type_Guid>
      <Business_ID>010170</Business_ID>
      <Product_Name>MOTO_pack</Product_Name>
      <Product_To_Product xsi:type="Product_Relation" ID="38224fc0-1a65-4b8e-9985-2277c99bbebf" Pattern="Relation_Entity">
         <Association_Start_Date>2015-02-23</Association_Start_Date>
         <Association_End_Date>2015-04-15</Association_End_Date>
         <Product xsi:type="New_Test_template" Path="/Component/Product/Launch_Entity" BusinessID="009154" ID="da80790a-0523-472c-89b0-208d919fcf73">
            <Name>idea_test</Name>
            <Category_ID Product_Line_ID="5">8</Category_ID>
            <Effective_Start_Date>2015-02-19</Effective_Start_Date>
            <Available_Start_Date>2015-02-19</Available_Start_Date>
            <Element_Guid>da80790a-0523-472c-89b0-208d919fcf73</Element_Guid>
            <Element_Type_Guid>0a7fb9ea-95c4-4eed-a716-ca588f8dcae8</Element_Type_Guid>
            <Business_ID>009154</Business_ID>
            <Product_Name>idea_test</Product_Name>
            <charge_role xsi:type="Lookup_Charge_Role" ID="6920b661-63de-45a0-94d4-900a4a873632" Pattern="Lookup">
               <Name>Recipient</Name>
               <Description>Recipient</Description>
            </charge_role>
         </Product>
      </Product_To_Product>
      <Product_To_Product xsi:type="Product_Relation" ID="eae5a5fd-1a27-4832-bdbe-c77907a77538" Pattern="Relation_Entity">
         <Association_Start_Date>2015-02-23</Association_Start_Date>
         <Association_End_Date>2015-04-10</Association_End_Date>
         <Product xsi:type="Component_Template" Path="/Product_Component/Component/Product/Launch_Entity" BusinessID="010169" ID="9f4a5a5b-1cb4-463b-b211-98f08fec2ce7">
            <Name>Moto-g</Name>
            <Category_ID Product_Line_ID="5">8</Category_ID>
            <Effective_Start_Date>2015-02-22</Effective_Start_Date>
            <Available_Start_Date>2015-02-23</Available_Start_Date>
            <Element_Guid>9f4a5a5b-1cb4-463b-b211-98f08fec2ce7</Element_Guid>
            <Element_Type_Guid>26c0d089-259b-444b-842a-e42d21dea778</Element_Type_Guid>
            <Business_ID>010169</Business_ID>
            <Product_Name>Moto-g</Product_Name>
            <Product_To_Product xsi:type="Product_Relation" ID="96ef93fd-ba40-4628-b22a-92c03e606a89" Pattern="Relation_Entity">
               <Association_Start_Date>2015-02-23</Association_Start_Date>
               <Product xsi:type="New_Test_template" Path="/Component/Product/Launch_Entity" BusinessID="009154" ID="da80790a-0523-472c-89b0-208d919fcf73">
                  <Name>idea_test</Name>
                  <Category_ID Product_Line_ID="5">8</Category_ID>
                  <Effective_Start_Date>2015-02-19</Effective_Start_Date>
                  <Available_Start_Date>2015-02-19</Available_Start_Date>
                  <Element_Guid>da80790a-0523-472c-89b0-208d919fcf73</Element_Guid>
                  <Element_Type_Guid>0a7fb9ea-95c4-4eed-a716-ca588f8dcae8</Element_Type_Guid>
                  <Business_ID>009154</Business_ID>
                  <Product_Name>idea_test</Product_Name>
                  <charge_role xsi:type="Lookup_Charge_Role" ID="6920b661-63de-45a0-94d4-900a4a873632" Pattern="Lookup">
                     <Name>Recipient</Name>
                     <Description>Recipient</Description>
                  </charge_role>
               </Product>
            </Product_To_Product>
         </Product>
      </Product_To_Product>
   </Package>
</Root>

在这里,如果带有任何产品的Association_End_Date过时,我想删除整个Product_To_Product元素。为此,我写了下面的代码,我通过C#函数比较日期,但我仍然无法删除实体。请告诉我哪里出错了。 XSLT代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:msxsl
="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:cs
="urn:cs">
<xsl:output method="xml" version="1.0" encoding="UTF‐8" indent="yes"/>
<msxsl:script language="C#" implements-prefix="cs">
 <![CDATA[public static long compareDate(long Asso_End_Date)
{
DateTime date1 = new DateTime(Asso_End_Date);
DateTime date2 = DateTime.Now;
long result;
result = date2.Date.CompareTo(date1.Date);
return(result);
}]]>
</msxsl:script>
<!-- TEMPLATE #1 -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

<!-- TEMPLATE #2 -->
<xsl:template name="mode1">
  <xsl:apply-templates select="Product_To_Product[Association_End_Date]"/>
</xsl:template>
<xsl:template name="mode2">
<xsl:variable name="date"/><xsl:value-of select="Product_To_Product[Association_End_Date]"/>
<xsl:choose>
    <xsl:when test="cs:compareDate($date) &gt; 0">
        <xsl:call-template name='mode1'/>
    </xsl:when>
    <xsl:otherwise>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

您的XSLT存在许多问题。首先,正如Lingamurthy CS在评论中所提到的,你有一个名为mode2的命名模板,但没有任何东西在调用该模板,因此它永远不会被使用。它应该真的改为模板匹配

<xsl:template match="Product_To_Product[Association_End_Date]">

其次,您对定义date变量的方式存在疑问。

 <xsl:variable name="date"/>

换句话说,你没有定义它。它实际上是空的。变量声明后面的xsl:value-of根本不会影响它。你应该这样定义

<xsl:variable name="date" select="Association_End_Date"/>

第三,您的C#函数本身存在问题

public static long compareDate(long Asso_End_Date)

参数的类型为long,但您不是传递long,而是传递字符串。该函数应该看起来像这样,因此它可以解析字符串

public static long compareDate(string Asso_End_Date)
{
DateTime date1 = DateTime.Parse(Asso_End_Date);
DateTime date2 = DateTime.Now;
long result;
result = date2.Date.CompareTo(date1.Date);
return(result)
}

另外,在查看通话结果时,您可能需要将&gt;替换为&lt;

试试这个XSLT(还要注意不需要mode1模板。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:cs="urn:cs">
<xsl:output method="xml" version="1.0" encoding="UTF‐8" indent="yes"/>
<msxsl:script language="C#" implements-prefix="cs">
 <![CDATA[public static long compareDate(string Asso_End_Date)
{
DateTime date1 = DateTime.Parse(Asso_End_Date);
DateTime date2 = DateTime.Now;
long result;
result = date2.Date.CompareTo(date1.Date);
return(result);
}]]>
</msxsl:script>

  <xsl:template match="node()|@*" name="identity">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Product_To_Product[Association_End_Date]">
    <xsl:variable name="date" select="Association_End_Date"/>
    <xsl:choose>
        <xsl:when test="cs:compareDate($date) &lt;= 0">
          <xsl:call-template name="identity" />
        </xsl:when>
        <xsl:otherwise>
        </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

或者更好的是,将条件放在模板匹配中,以简化它:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:cs="urn:cs">
<xsl:output method="xml" version="1.0" encoding="UTF‐8" indent="yes"/>
<msxsl:script language="C#" implements-prefix="cs">
 <![CDATA[public static long compareDate(string Asso_End_Date)
{
DateTime date1 = DateTime.Parse(Asso_End_Date);
DateTime date2 = DateTime.Now;
long result;
result = date2.Date.CompareTo(date1.Date);
return(result);
}]]>
</msxsl:script>

  <xsl:template match="node()|@*" name="identity">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Product_To_Product[cs:compareDate(Association_End_Date) &gt; 0]" />
</xsl:stylesheet>