如何仅序列化节点的整数部分

时间:2016-12-28 04:56:41

标签: c# xml

<!-- Create some meta data. Use this to look up the running total based on the 
     node-id(.) of a TestInstance
 -->
<xsl:variable name="test">
  <xsl:apply-templates select="//Test1|//Test2|//Test3|//Test4|//Test5|//Test6|//Test7|//Test8|//Test9|//Test10" mode="metadata"/>
</xsl:variable>

<!--  Only use node-set for version 1.0. -->
<xsl:variable name="testList" select="msxml:node-set($test)"/>

<!-- Mode to create elements that contain the metadata. -->
<xsl:template match="//Test1|//Test2|//Test3|//Test4|//Test5|//Test6|//Test7|//Test8|//Test9|//Test10" mode="metadata">
  <xsl:element name="element">
    <xsl:element name="id">
      <xsl:value-of select="generate-id(.)"/>
    </xsl:element> 
    <xsl:element name="TestInstanceID">
      <!-- Get the TestInstance. -->
      <xsl:value-of select="generate-id(../..)"/>
    </xsl:element>
    <xsl:element name="TestListID">
      <!-- Get the TestInstance. -->
      <xsl:value-of select="generate-id(..)"/>
    </xsl:element>
    <xsl:element name="TotalTime">
      <xsl:call-template name="getCleanNumber">
        <xsl:with-param name="inNumStr" select="TotalTime"/>
      </xsl:call-template>
    </xsl:element>
  </xsl:element>
</xsl:template>

<!-- Get a distinct list of TestInstanceID's. -->
<xsl:variable name="distinctTestInstanceIDs">
  <xsl:copy-of select="$testList/element[not(TestInstanceID=preceding-sibling::element/TestInstanceID)]"/>
</xsl:variable>

<!--  Only use node-set for version 1.0. -->
<xsl:variable name="distinctTestInstanceIDsList" select="msxml:node-set($distinctTestInstanceIDs)"/>

<!-- Group the metadata based on distinctTestInstanceIDs. -->
<xsl:variable name="groupedTestInstance">
  <xsl:for-each select="$distinctTestInstanceIDsList/element/TestInstanceID">
    <xsl:variable name="TestInstanceID" select="."/>
    <xsl:element name="element">
      <xsl:element name="TestInstanceID">
        <!-- Get the TestInstance. -->
        <xsl:value-of select="."/>
      </xsl:element>
      <xsl:element name="TotalTime">
        <xsl:value-of select="sum($testList/element[TestInstanceID=$TestInstanceID]/TotalTime)"/>
      </xsl:element>
    </xsl:element>
  </xsl:for-each>
</xsl:variable>

<!--  Only use node-set for version 1.0. -->
<xsl:variable name="groupedTestInstanceList" select="msxml:node-set($groupedTestInstance)"/>


<!-- Now create the rolling totals. -->
<xsl:variable name="rollingTotals">
  <xsl:call-template name="generateRollingTotals">
    <xsl:with-param name="index" select="1"/>
    <xsl:with-param name="rollingTotal" select="0"/>
  </xsl:call-template>
</xsl:variable>

<!--  Only use node-set for version 1.0. -->
<xsl:variable name="rollingTotalsList" select="msxml:node-set($rollingTotals)"/>

<!-- Use the rollingTotalsList to lookup the rolling total for a TestInstance.

     Create a variable the contains the node-id of the TextIntance for which you 
     want the rolling total.

     <xsl:variable name="TestInstanceID" select="generate-id(.)"/>  etc.

    Use this variable for the lookup.

-->

<!-- Recursive template to create rolling totals. -->
<xsl:template name="generateRollingTotals">
  <xsl:param name="index"/>
  <xsl:param name="rollingTotal"/>

  <xsl:if test="$index &lt;= count($groupedTestInstanceList/element)">
    <xsl:element name="element">
      <xsl:element name="TestInstanceID">
        <!-- Get the TestInstance. -->
        <xsl:value-of select="$groupedTestInstanceList/element[$index]/TestInstanceID"/>
      </xsl:element>
      <xsl:element name="rollingTotalTime">
        <xsl:value-of select="$groupedTestInstanceList/element[$index]/TotalTime + $rollingTotal"/>
      </xsl:element>
    </xsl:element>

    <xsl:call-template name="generateRollingTotals">
      <xsl:with-param name="index" select="$index + 1"/>
      <xsl:with-param name="rollingTotal" select="$groupedTestInstanceList/element[$index]/TotalTime + $rollingTotal"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>


<xsl:template name="getCleanNumber">
  <xsl:param name="inNumStr"/>
  <!-- Clean up the number.  Get the digits and decimal point only. -->
  <xsl:variable name="rawNum" select="translate($inNumStr,translate($inNumStr,'0123456789.',''),'')"/>
  <!-- Get the number. -->
  <xsl:variable name="num">
    <xsl:choose>
      <xsl:when test="$rawNum='' or $rawNum=0">
        <xsl:value-of select="0"/>
      </xsl:when>
      <xsl:when test="contains($inNumStr,'-') or contains($inNumStr,'(')">
        <xsl:value-of select="concat('-',$rawNum)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$rawNum"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:value-of select="$num"/>
</xsl:template>

这里ACTUALQTY,RATE既有整数也有字符串部分,我只需要整数部分,我该怎么做

2 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,您想从XML中提取小数和整数部分。所以其中一个解决方案可能是

XDocument xdoc = XDocument.Load("YourXMLFile");
var qty = xdoc.Descendants("ACTUALQTY").FirstOrDefault().Value;
string resultString = Regex.Match(qty, @"\d+").Value;
decimal actqty;
decimal.TryParse(resultString, out actqty);

var rt = xdoc.Descendants("RATE").FirstOrDefault().Value;
string resultRate = Regex.Match(rt, @"^-?\d+(?:\.\d+)?").Value;
decimal actrt;
decimal.TryParse(resultRate, out actrt);

我尝试使用该解决方案的是qty我们首先获得ACTUALQTY的值500 pcs然后使用正则表达式我们只从字符串中提取数字部分而我们获取500然后只使用decimal.TryParse将其转换为名为actqty的十进制数,以便将actqty分配给objpordetails.QUANTITY

现在为Rate尝试了几乎相同的概念,但由于值为12059.00/pcs,如果我们使用"\d+"执行正则表达式,我们只会获得12059而不是小数它的一部分所以一个新的正则表达式"^-?\d+(?:\.\d+)?"用于提取字符串12059.00/pcs的小数部分,它将变为12059.00,然后你可以分配{{1}的值转到actrt

希望这会对你有所帮助

答案 1 :(得分:0)

如果数据格式相同,您可以使用以下代码

XElement xmlFileContent = XElement.Load("filePath");
        var datas=  xmlFileContent.Elements("INVENTORYALLOCATIONS.LIST")
            .Select(i =>
            {
               return new
                {
                    Rate = i.Element("RATE").Value.Split('/')[0],
                    Actualqty = i.Element("ACTUALQTY").Value.Trim().Split(' ')[0]
                };
            }).ToList();  

数据包含具有Rate和Actualqty属性的对象。