<!-- 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 <= 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既有整数也有字符串部分,我只需要整数部分,我该怎么做
答案 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属性的对象。