XSLT 范围问题?
XSLT scoping issue?
正在使用新信息更新此 post。我附上了整个 XSLT,因为它相当复杂,而且我不完全确定要保留什么以保持问题的完整性和原因。此外,我将尽可能减少输入,以保持数据的完整性。我不包括的是 EDI X12 856 的 xsd。这是专有的,它也非常大。如果您使用的是 Biztalk EDI,则您已经拥有必要的架构。如果我可以从此架构中提供有助于回答此问题的信息,请告诉我,我会 post 满足您的任何需求。如果有什么地方我可以把 .xsd 放在存储库或电子邮件中,请告诉我。
问题是我试图接触到 LIN/LIN11 元素并将每次迭代的内容放入 DTM02 元素中。我要么缺少执行此操作的语法,要么我可能需要一些全局变量来遍历实例。但对于 XSLT 及其处理来说确实是新手。真的可以使用一些方向和解决方案会很棒。
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var ScriptNS0 userCSharp"
version="1.0"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:ScriptNS0="http://schemas.microsoft.com/BizTalk/2003/ScriptNS0"
xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:template match="/">
<xsl:apply-templates select="/ns0:X12_00401_856" />
</xsl:template>
<xsl:template match="/ns0:X12_00401_856">
<xsl:variable name="var:BSN05" select="userCSharp:StringConcat("0001")" />
<xsl:if test="userCSharp:InistrLastPackID()" />
<xsl:variable name="var:OrderNo" select="ns0:HLLoop1[ns0:HL/HL03='O']/ns0:PRF/PRF01" />
<xsl:variable name="var:PurchaseOrderNo" select="ns0:HLLoop1[ns0:HL/HL03='O']/ns0:PRF/PRF06" />
<ns0:X12_00401_856>
<ns0:BSN>
<BSN01>
<xsl:text>00</xsl:text>
</BSN01>
<BSN02>
<xsl:value-of select="ns0:BSN/BSN02/text()" />
</BSN02>
<xsl:variable name="var:v1" select="ScriptNS0:GetEDIDate(string(ns0:BSN/BSN03/text()))" />
<xsl:variable name="var:v2" select="userCSharp:LogicalNe(string($var:v1) , "")" />
<xsl:if test="string($var:v2)='true'">
<xsl:variable name="var:v3" select="ns0:BSN/BSN03/text()" />
<BSN03>
<xsl:value-of select="$var:v3" />
</BSN03>
</xsl:if>
<BSN04>
<xsl:value-of select="ns0:BSN/BSN04/text()" />
</BSN04>
<BSN05>
<xsl:value-of select="$var:BSN05" />
</BSN05>
</ns0:BSN>
<!--Inital the strLastPackID in the begining of the template-->
<!--Shipment-->
<xsl:element name="ns0:HLLoop1">
<xsl:variable name="var:ShipmentHLLoop1" select="ns0:HLLoop1[ns0:HL/HL03='S']" />
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('S')" />
</xsl:element>
<xsl:element name="HL03">S</xsl:element>
</xsl:element>
<xsl:variable name="var:v35" select="userCSharp:StringConcat('BM')" />
<xsl:variable name="var:v36" select="userCSharp:StringConcat('5774125')" />
<xsl:variable name="var:v37" select="userCSharp:StringConcat('SN')" />
<xsl:variable name="var:v38" select="userCSharp:StringConcat('IA')" />
<xsl:variable name="var:v40" select="$var:v35" />
<xsl:variable name="var:v41" select="$var:v36" />
<xsl:variable name="var:v42" select="$var:v37" />
<xsl:variable name="var:v43" select="ns0:TD3/TD303/text()" />
<xsl:variable name="var:v44" select="$var:v38" />
<xsl:variable name="var:v46" select="ScriptNS0:GetRollaShipmentByOrderNo(string($var:OrderNo/text()))" />
<xsl:variable name="var:v47" select="ScriptNS0:PullElementAfterQualifier('VehID', string($var:v46))" />
<!--Ship To-->
<xsl:element name="ns0:N1Loop1">
<xsl:variable name="var:STN1Loop1" select="$var:ShipmentHLLoop1/ns0:N1Loop1[ns0:N1/N101='ST']" />
<xsl:element name="ns0:N1">
<xsl:element name="N101">ST</xsl:element>
<xsl:element name="N102">
<xsl:value-of select="$var:STN1Loop1/ns0:N1/N102" />
</xsl:element>
<xsl:element name="N103">92</xsl:element>
<xsl:element name="N104">
<xsl:value-of select="$var:STN1Loop1/ns0:N1/N104" />
</xsl:element>
</xsl:element>
<!--End of N1-->
</xsl:element>
<!--End of N1Loop1-->
</xsl:element>
<!--End of HLLoop1-->
<!--Order-->
<xsl:element name="ns0:HLLoop1">
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('O')" />
</xsl:element>
<xsl:element name="HL02">
<xsl:value-of select="userCSharp:ReturnHL02('S')" />
</xsl:element>
<xsl:element name="HL03">O</xsl:element>
</xsl:element>
<!--End HL-->
<xsl:element name="ns0:PRF">
<xsl:element name="PRF01">
<xsl:value-of select="$var:PurchaseOrderNo" />
</xsl:element>
</xsl:element>
<!--End PRF-->
</xsl:element>
<!--End HLLoop1-->
<xsl:for-each select="ns0:HLLoop1">
<!--don't include S or O levels-->
<xsl:if test="ns0:HL/HL03 = 'T' or ns0:HL/HL03 = 'I'">
<!--Pack-->
<xsl:if test="ns0:HL/HL03 = 'T'">
<xsl:element name="ns0:HLLoop1">
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('T')" />
</xsl:element>
<xsl:element name="HL02">
<xsl:value-of select="userCSharp:ReturnHL02('O')" />
</xsl:element>
<xsl:element name="HL03">T</xsl:element>
</xsl:element>
<xsl:element name="ns0:MAN">
<xsl:element name="MAN01">GM</xsl:element>
<xsl:element name="MAN02">
<xsl:value-of select="ns0:MAN/MAN02" />
</xsl:element>
</xsl:element>
<!--End of MAN-->
<xsl:element name="ns0:DTM_2">
<xsl:element name="DTM01">036</xsl:element>
<xsl:element name="DTM02">
<xsl:value-of select="ns0:LIN/LIN11" />
</xsl:element>
</xsl:element>
</xsl:element>
<!--End of HLLoop1 Pack-->
</xsl:if>
<!--Item-->
<xsl:if test="ns0:HL/HL03 = 'I'">
<!--Item-->
<xsl:element name="ns0:HLLoop1">
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('I')" />
</xsl:element>
<xsl:element name="HL02">
<xsl:value-of select="userCSharp:ReturnHL02('T')" />
</xsl:element>
<xsl:element name="HL03">I</xsl:element>
</xsl:element>
<xsl:element name="ns0:LIN">
<xsl:element name="LIN01">
<xsl:value-of select="ns0:LIN/LIN01 div 10000" />
</xsl:element>
<xsl:element name="LIN02">UP</xsl:element>
<xsl:element name="LIN03">
<xsl:value-of select="ns0:LIN/LIN03" />
</xsl:element>
</xsl:element>
<!--End of LIN-->
<xsl:element name="SN1">
<xsl:element name="SN102">
<xsl:value-of select="ns0:SN1/SN102" />
</xsl:element>
<xsl:element name="SN103">EA</xsl:element>
</xsl:element>
<!--End of SN1-->
</xsl:element>
<!--End of HLLoop1 Item-->
</xsl:if>
</xsl:if>
</xsl:for-each>
<!--End of Pack/Item For Each-->
</ns0:X12_00401_856>
</xsl:template>
<msxsl:script language="C#" implements-prefix="userCSharp">
<![CDATA[
int HL01 = 0;
int ShipHL = 0;
int OrdrHL = 0;
int PackHL = 0;
int ItemHL = 0;
//This function increments the hl01 value then stores the value into the
//appropriate "last" object variable. It returns the value of hl01 to the
//XSLT script.
public string ReturnHL01(string LevelCode)
{
HL01 += 1;
if (LevelCode == "S")
ShipHL = HL01;
if (LevelCode == "O")
OrdrHL = HL01;
if (LevelCode == "P")
PackHL = HL01;
if (LevelCode == "I")
ItemHL = HL01;
return HL01.ToString();
}
public string ReplaceMe(string str_Input)
{
return str_Input.Replace("-","");
}
public string ReturnQTY(string str_Qty, string str_QtyPerUOM)
{
string[] strarrayQty = str_Qty.Split('.');
string[] strarrayQtyPerUOM = str_QtyPerUOM.Split('.');
str_Qty = strarrayQty[0];
str_QtyPerUOM = strarrayQtyPerUOM[0];
int int_Qty = Convert.ToInt32(str_Qty);
int int_QtyPerUOM = Convert.ToInt32(str_QtyPerUOM);
return (int_Qty * int_QtyPerUOM).ToString();
}
//This function returns the HL02
public string ReturnHL02(string LevelCode)
{
int retlevel = 0;
if (LevelCode == "S")
retlevel = ShipHL;
if (LevelCode == "O")
retlevel = OrdrHL;
if (LevelCode == "P")
retlevel = PackHL;
if (LevelCode == "I")
retlevel = ItemHL;
return retlevel.ToString();
}
/*This Function used to check if the current pack is the same with previous pack,
if the pack is the same, then return string "1", if it is difference, then return "0" */
string strLastPackID;
public void InistrLastPackID()
{
strLastPackID = "";
}
public string CheckIfTheSamePack(string strCurrentPackID)
{
if (strLastPackID == strCurrentPackID)
{
return "1";
}
else
{
strLastPackID = strCurrentPackID;
return "0";
}
}
public string GetReleaseFromPORelease(string str_PO)
{
if (str_PO.Contains("_"))
{
string[] strarray_PO = str_PO.Split('_');
return strarray_PO[1];
}
else
{
return str_PO;
}
}
public string GetMars856STCode(string str_CustomerNumber, string str_STState)
{
string duns;
if (str_CustomerNumber.Contains("NUTRO"))
{
switch (str_STState)
{
case "CA":
duns = "007134919000Y";
break;
case "TN":
duns = "007134919000U";
break;
default:
duns = "BADDUNS";
break;
}
return duns;
}
else
{
switch (str_STState)
{
case "CA":
duns = "0071349190097";
break;
case "GA":
duns = "0071349190031";
break;
case "TX":
duns = "0071349190079";
break;
case "SC":
duns = "0071349190096";
break;
case "OH":
duns = "0071349190041";
break;
default:
duns = "BADDUNS";
break;
}
return duns;
}
}
public string MathDivide(string val1, string val2)
{
string retval = "";
double d1 = 0;
double d2 = 0;
if (IsNumeric1(val1, ref d1) && IsNumeric1(val2, ref d2))
{
if (d2 != 0)
{
double ret = d1 / d2;
retval = ret.ToString();
}
}
return retval;
}
public bool IsNumeric1(string val)
{
if (val == null)
{
return false;
}
double d = 0;
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public bool IsNumeric1(string val, ref double d)
{
if (val == null)
{
return false;
}
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public string StringConcat(string param0)
{
return param0;
}
public bool LogicalNe(string val1, string val2)
{
bool ret = false;
double d1 = 0;
double d2 = 0;
if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
{
ret = d1 != d2;
}
else
{
ret = String.Compare(val1, val2, StringComparison.Ordinal) != 0;
}
return ret;
}
public bool IsNumeric(string val)
{
if (val == null)
{
return false;
}
double d = 0;
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public bool IsNumeric(string val, ref double d)
{
if (val == null)
{
return false;
}
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public string GetExpirationDate(string str_Mfg_Date, string str_Shelf_Life)
{
DateTime dt = System.Convert.ToDateTime(str_Mfg_Date);
dt = dt.AddDays(System.Convert.ToInt32(str_Shelf_Life));
return dt.ToString("yyyyMMdd");
}
]]></msxsl:script>
</xsl:stylesheet>
输入数据:
<?xml version="1.0" encoding="utf-8"?>
<ns0:X12_00401_856 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
<ST>
<ST01>856</ST01>
<ST02>0001</ST02>
</ST>
<ns0:BSN>
<BSN01>00</BSN01>
<BSN02>SID0000378</BSN02>
<BSN03>20160824</BSN03>
<BSN04>172952</BSN04>
<BSN05>0001</BSN05>
</ns0:BSN>
<ns0:HLLoop1>
<ns0:HL>
<HL01>1</HL01>
<HL03>S</HL03>
</ns0:HL>
<ns0:TD1>
<TD101>PLT94</TD101>
<TD102>4</TD102>
<TD106>G</TD106>
<TD107>52448.00</TD107>
<TD108>LB</TD108>
</ns0:TD1>
<ns0:TD5>
<TD502>2</TD502>
<TD503>ANSH</TD503>
<TD504>M</TD504>
</ns0:TD5>
<ns0:TD3>
<TD301>TL</TD301>
<TD309>TRL0000590</TD309>
</ns0:TD3>
<ns0:REF>
<REF01>SN</REF01>
<REF02>SEAL082401</REF02>
</ns0:REF>
<ns0:REF>
<REF01>BM</REF01>
<REF02>10401217</REF02>
</ns0:REF>
<ns0:DTM_2>
<DTM01>011</DTM01>
<DTM02>20160819</DTM02>
</ns0:DTM_2>
<ns0:N1Loop1>
<ns0:N1>
<N101>SF</N101>
<N102>any name</N102>
<N103>92</N103>
<N104>61</N104>
</ns0:N1>
<ns0:N3>
<N301>101 Your WAY</N301>
</ns0:N3>
<ns0:N4>
<N401>Irvine</N401>
<N402>CA</N402>
<N403>91111</N403>
<N404>USA</N404>
</ns0:N4>
</ns0:N1Loop1>
<ns0:N1Loop1>
<ns0:N1>
<N101>ST</N101>
<N102>0010</N102>
<N103>92</N103>
<N104>0010</N104>
</ns0:N1>
<ns0:N3>
<N301>1234 My Way Ct</N301>
</ns0:N3>
<ns0:N4>
<N401>GROVEPORT</N401>
<N402>OH</N402>
<N403>43125</N403>
<N404>USA</N404>
</ns0:N4>
</ns0:N1Loop1>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>2</HL01>
<HL03>O</HL03>
</ns0:HL>
<ns0:PRF>
<PRF01>10401217</PRF01>
<PRF04>20160822</PRF04>
<PRF06>10401217</PRF06>
<PRF07>KN</PRF07>
</ns0:PRF>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>3</HL01>
<HL03>T</HL03>
</ns0:HL>
<ns0:MAN>
<MAN01>GM</MAN01>
<MAN02>L000000000T5</MAN02>
</ns0:MAN>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>4</HL01>
<HL03>I</HL03>
</ns0:HL>
<ns0:LIN>
<LIN01>20000</LIN01>
<LIN02>UP</LIN02>
<LIN03>030111169051</LIN03>
<LIN04>VN</LIN04>
<LIN05>416905</LIN05>
<LIN10>RU</LIN10>
<LIN11>20180614</LIN11>
</ns0:LIN>
<ns0:SN1>
<SN102>32</SN102>
<SN103>EA</SN103>
</ns0:SN1>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>5</HL01>
<HL03>T</HL03>
</ns0:HL>
<ns0:MAN>
<MAN01>GM</MAN01>
<MAN02>L000000000T6</MAN02>
</ns0:MAN>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>6</HL01>
<HL03>I</HL03>
</ns0:HL>
<ns0:LIN>
<LIN01>20000</LIN01>
<LIN02>UP</LIN02>
<LIN03>030111169051</LIN03>
<LIN04>VN</LIN04>
<LIN05>416905</LIN05>
<LIN10>RU</LIN10>
<LIN11>20180614</LIN11>
</ns0:LIN>
<ns0:SN1>
<SN102>32</SN102>
<SN103>EA</SN103>
</ns0:SN1>
</ns0:HLLoop1>
<ns0:CTT>
<CTT01>6</CTT01>
</ns0:CTT>
<SE>
<SE01>79</SE01>
<SE02>0001</SE02>
</SE>
</ns0:X12_00401_856>
当 HL03
= 'T'
时,您的 XSLT 仅输出 DTM
个节点,但您的输入文档只有 LIN/LIN11
,其中 HL03
是别的东西 (I
).
如果想在没有LIN11的情况下不输出DTM节点,可以这样:
<!--Pack-->
<xsl:if test="ns0:HL/HL03 = 'T'">
<xsl:element name="ns0:HLLoop1">
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('T')" />
</xsl:element>
<xsl:element name="HL02">
<xsl:value-of select="userCSharp:ReturnHL02('O')" />
</xsl:element>
<xsl:element name="HL03">T</xsl:element>
</xsl:element>
<xsl:element name="ns0:MAN">
<xsl:element name="MAN01">GM</xsl:element>
<xsl:element name="MAN02">
<xsl:value-of select="ns0:MAN/MAN02" />
</xsl:element>
</xsl:element>
<!--End of MAN-->
<xsl:if test="ns0:LIN/LIN11">
<xsl:element name="ns0:DTM_2">
<xsl:element name="DTM01">036</xsl:element>
<xsl:element name="DTM02">
<xsl:value-of select="ns0:LIN/LIN11"/>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:element>
<!--End of HLLoop1 Pack-->
</xsl:if>
如果你需要下面的LIN11
节点,你可以使用这样的代码:
<xsl:element name="DTM02">
<xsl:value-of select="following::LIN11[1]"/>
</xsl:element>
但这似乎很可疑并且容易被破坏(如果没有跟随 LIN11 怎么办,如果它是 10 个 HL 循环并被多次重复使用怎么办,等等...)。您可能最好获得具有 HL03 = 'I'
的 following
HL 循环,也许使用类似此处 XSLT: Loop selecting two elements at a time
的内容
正在使用新信息更新此 post。我附上了整个 XSLT,因为它相当复杂,而且我不完全确定要保留什么以保持问题的完整性和原因。此外,我将尽可能减少输入,以保持数据的完整性。我不包括的是 EDI X12 856 的 xsd。这是专有的,它也非常大。如果您使用的是 Biztalk EDI,则您已经拥有必要的架构。如果我可以从此架构中提供有助于回答此问题的信息,请告诉我,我会 post 满足您的任何需求。如果有什么地方我可以把 .xsd 放在存储库或电子邮件中,请告诉我。
问题是我试图接触到 LIN/LIN11 元素并将每次迭代的内容放入 DTM02 元素中。我要么缺少执行此操作的语法,要么我可能需要一些全局变量来遍历实例。但对于 XSLT 及其处理来说确实是新手。真的可以使用一些方向和解决方案会很棒。
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var ScriptNS0 userCSharp"
version="1.0"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:ScriptNS0="http://schemas.microsoft.com/BizTalk/2003/ScriptNS0"
xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:template match="/">
<xsl:apply-templates select="/ns0:X12_00401_856" />
</xsl:template>
<xsl:template match="/ns0:X12_00401_856">
<xsl:variable name="var:BSN05" select="userCSharp:StringConcat("0001")" />
<xsl:if test="userCSharp:InistrLastPackID()" />
<xsl:variable name="var:OrderNo" select="ns0:HLLoop1[ns0:HL/HL03='O']/ns0:PRF/PRF01" />
<xsl:variable name="var:PurchaseOrderNo" select="ns0:HLLoop1[ns0:HL/HL03='O']/ns0:PRF/PRF06" />
<ns0:X12_00401_856>
<ns0:BSN>
<BSN01>
<xsl:text>00</xsl:text>
</BSN01>
<BSN02>
<xsl:value-of select="ns0:BSN/BSN02/text()" />
</BSN02>
<xsl:variable name="var:v1" select="ScriptNS0:GetEDIDate(string(ns0:BSN/BSN03/text()))" />
<xsl:variable name="var:v2" select="userCSharp:LogicalNe(string($var:v1) , "")" />
<xsl:if test="string($var:v2)='true'">
<xsl:variable name="var:v3" select="ns0:BSN/BSN03/text()" />
<BSN03>
<xsl:value-of select="$var:v3" />
</BSN03>
</xsl:if>
<BSN04>
<xsl:value-of select="ns0:BSN/BSN04/text()" />
</BSN04>
<BSN05>
<xsl:value-of select="$var:BSN05" />
</BSN05>
</ns0:BSN>
<!--Inital the strLastPackID in the begining of the template-->
<!--Shipment-->
<xsl:element name="ns0:HLLoop1">
<xsl:variable name="var:ShipmentHLLoop1" select="ns0:HLLoop1[ns0:HL/HL03='S']" />
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('S')" />
</xsl:element>
<xsl:element name="HL03">S</xsl:element>
</xsl:element>
<xsl:variable name="var:v35" select="userCSharp:StringConcat('BM')" />
<xsl:variable name="var:v36" select="userCSharp:StringConcat('5774125')" />
<xsl:variable name="var:v37" select="userCSharp:StringConcat('SN')" />
<xsl:variable name="var:v38" select="userCSharp:StringConcat('IA')" />
<xsl:variable name="var:v40" select="$var:v35" />
<xsl:variable name="var:v41" select="$var:v36" />
<xsl:variable name="var:v42" select="$var:v37" />
<xsl:variable name="var:v43" select="ns0:TD3/TD303/text()" />
<xsl:variable name="var:v44" select="$var:v38" />
<xsl:variable name="var:v46" select="ScriptNS0:GetRollaShipmentByOrderNo(string($var:OrderNo/text()))" />
<xsl:variable name="var:v47" select="ScriptNS0:PullElementAfterQualifier('VehID', string($var:v46))" />
<!--Ship To-->
<xsl:element name="ns0:N1Loop1">
<xsl:variable name="var:STN1Loop1" select="$var:ShipmentHLLoop1/ns0:N1Loop1[ns0:N1/N101='ST']" />
<xsl:element name="ns0:N1">
<xsl:element name="N101">ST</xsl:element>
<xsl:element name="N102">
<xsl:value-of select="$var:STN1Loop1/ns0:N1/N102" />
</xsl:element>
<xsl:element name="N103">92</xsl:element>
<xsl:element name="N104">
<xsl:value-of select="$var:STN1Loop1/ns0:N1/N104" />
</xsl:element>
</xsl:element>
<!--End of N1-->
</xsl:element>
<!--End of N1Loop1-->
</xsl:element>
<!--End of HLLoop1-->
<!--Order-->
<xsl:element name="ns0:HLLoop1">
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('O')" />
</xsl:element>
<xsl:element name="HL02">
<xsl:value-of select="userCSharp:ReturnHL02('S')" />
</xsl:element>
<xsl:element name="HL03">O</xsl:element>
</xsl:element>
<!--End HL-->
<xsl:element name="ns0:PRF">
<xsl:element name="PRF01">
<xsl:value-of select="$var:PurchaseOrderNo" />
</xsl:element>
</xsl:element>
<!--End PRF-->
</xsl:element>
<!--End HLLoop1-->
<xsl:for-each select="ns0:HLLoop1">
<!--don't include S or O levels-->
<xsl:if test="ns0:HL/HL03 = 'T' or ns0:HL/HL03 = 'I'">
<!--Pack-->
<xsl:if test="ns0:HL/HL03 = 'T'">
<xsl:element name="ns0:HLLoop1">
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('T')" />
</xsl:element>
<xsl:element name="HL02">
<xsl:value-of select="userCSharp:ReturnHL02('O')" />
</xsl:element>
<xsl:element name="HL03">T</xsl:element>
</xsl:element>
<xsl:element name="ns0:MAN">
<xsl:element name="MAN01">GM</xsl:element>
<xsl:element name="MAN02">
<xsl:value-of select="ns0:MAN/MAN02" />
</xsl:element>
</xsl:element>
<!--End of MAN-->
<xsl:element name="ns0:DTM_2">
<xsl:element name="DTM01">036</xsl:element>
<xsl:element name="DTM02">
<xsl:value-of select="ns0:LIN/LIN11" />
</xsl:element>
</xsl:element>
</xsl:element>
<!--End of HLLoop1 Pack-->
</xsl:if>
<!--Item-->
<xsl:if test="ns0:HL/HL03 = 'I'">
<!--Item-->
<xsl:element name="ns0:HLLoop1">
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('I')" />
</xsl:element>
<xsl:element name="HL02">
<xsl:value-of select="userCSharp:ReturnHL02('T')" />
</xsl:element>
<xsl:element name="HL03">I</xsl:element>
</xsl:element>
<xsl:element name="ns0:LIN">
<xsl:element name="LIN01">
<xsl:value-of select="ns0:LIN/LIN01 div 10000" />
</xsl:element>
<xsl:element name="LIN02">UP</xsl:element>
<xsl:element name="LIN03">
<xsl:value-of select="ns0:LIN/LIN03" />
</xsl:element>
</xsl:element>
<!--End of LIN-->
<xsl:element name="SN1">
<xsl:element name="SN102">
<xsl:value-of select="ns0:SN1/SN102" />
</xsl:element>
<xsl:element name="SN103">EA</xsl:element>
</xsl:element>
<!--End of SN1-->
</xsl:element>
<!--End of HLLoop1 Item-->
</xsl:if>
</xsl:if>
</xsl:for-each>
<!--End of Pack/Item For Each-->
</ns0:X12_00401_856>
</xsl:template>
<msxsl:script language="C#" implements-prefix="userCSharp">
<![CDATA[
int HL01 = 0;
int ShipHL = 0;
int OrdrHL = 0;
int PackHL = 0;
int ItemHL = 0;
//This function increments the hl01 value then stores the value into the
//appropriate "last" object variable. It returns the value of hl01 to the
//XSLT script.
public string ReturnHL01(string LevelCode)
{
HL01 += 1;
if (LevelCode == "S")
ShipHL = HL01;
if (LevelCode == "O")
OrdrHL = HL01;
if (LevelCode == "P")
PackHL = HL01;
if (LevelCode == "I")
ItemHL = HL01;
return HL01.ToString();
}
public string ReplaceMe(string str_Input)
{
return str_Input.Replace("-","");
}
public string ReturnQTY(string str_Qty, string str_QtyPerUOM)
{
string[] strarrayQty = str_Qty.Split('.');
string[] strarrayQtyPerUOM = str_QtyPerUOM.Split('.');
str_Qty = strarrayQty[0];
str_QtyPerUOM = strarrayQtyPerUOM[0];
int int_Qty = Convert.ToInt32(str_Qty);
int int_QtyPerUOM = Convert.ToInt32(str_QtyPerUOM);
return (int_Qty * int_QtyPerUOM).ToString();
}
//This function returns the HL02
public string ReturnHL02(string LevelCode)
{
int retlevel = 0;
if (LevelCode == "S")
retlevel = ShipHL;
if (LevelCode == "O")
retlevel = OrdrHL;
if (LevelCode == "P")
retlevel = PackHL;
if (LevelCode == "I")
retlevel = ItemHL;
return retlevel.ToString();
}
/*This Function used to check if the current pack is the same with previous pack,
if the pack is the same, then return string "1", if it is difference, then return "0" */
string strLastPackID;
public void InistrLastPackID()
{
strLastPackID = "";
}
public string CheckIfTheSamePack(string strCurrentPackID)
{
if (strLastPackID == strCurrentPackID)
{
return "1";
}
else
{
strLastPackID = strCurrentPackID;
return "0";
}
}
public string GetReleaseFromPORelease(string str_PO)
{
if (str_PO.Contains("_"))
{
string[] strarray_PO = str_PO.Split('_');
return strarray_PO[1];
}
else
{
return str_PO;
}
}
public string GetMars856STCode(string str_CustomerNumber, string str_STState)
{
string duns;
if (str_CustomerNumber.Contains("NUTRO"))
{
switch (str_STState)
{
case "CA":
duns = "007134919000Y";
break;
case "TN":
duns = "007134919000U";
break;
default:
duns = "BADDUNS";
break;
}
return duns;
}
else
{
switch (str_STState)
{
case "CA":
duns = "0071349190097";
break;
case "GA":
duns = "0071349190031";
break;
case "TX":
duns = "0071349190079";
break;
case "SC":
duns = "0071349190096";
break;
case "OH":
duns = "0071349190041";
break;
default:
duns = "BADDUNS";
break;
}
return duns;
}
}
public string MathDivide(string val1, string val2)
{
string retval = "";
double d1 = 0;
double d2 = 0;
if (IsNumeric1(val1, ref d1) && IsNumeric1(val2, ref d2))
{
if (d2 != 0)
{
double ret = d1 / d2;
retval = ret.ToString();
}
}
return retval;
}
public bool IsNumeric1(string val)
{
if (val == null)
{
return false;
}
double d = 0;
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public bool IsNumeric1(string val, ref double d)
{
if (val == null)
{
return false;
}
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public string StringConcat(string param0)
{
return param0;
}
public bool LogicalNe(string val1, string val2)
{
bool ret = false;
double d1 = 0;
double d2 = 0;
if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
{
ret = d1 != d2;
}
else
{
ret = String.Compare(val1, val2, StringComparison.Ordinal) != 0;
}
return ret;
}
public bool IsNumeric(string val)
{
if (val == null)
{
return false;
}
double d = 0;
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public bool IsNumeric(string val, ref double d)
{
if (val == null)
{
return false;
}
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
}
public string GetExpirationDate(string str_Mfg_Date, string str_Shelf_Life)
{
DateTime dt = System.Convert.ToDateTime(str_Mfg_Date);
dt = dt.AddDays(System.Convert.ToInt32(str_Shelf_Life));
return dt.ToString("yyyyMMdd");
}
]]></msxsl:script>
</xsl:stylesheet>
输入数据:
<?xml version="1.0" encoding="utf-8"?>
<ns0:X12_00401_856 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
<ST>
<ST01>856</ST01>
<ST02>0001</ST02>
</ST>
<ns0:BSN>
<BSN01>00</BSN01>
<BSN02>SID0000378</BSN02>
<BSN03>20160824</BSN03>
<BSN04>172952</BSN04>
<BSN05>0001</BSN05>
</ns0:BSN>
<ns0:HLLoop1>
<ns0:HL>
<HL01>1</HL01>
<HL03>S</HL03>
</ns0:HL>
<ns0:TD1>
<TD101>PLT94</TD101>
<TD102>4</TD102>
<TD106>G</TD106>
<TD107>52448.00</TD107>
<TD108>LB</TD108>
</ns0:TD1>
<ns0:TD5>
<TD502>2</TD502>
<TD503>ANSH</TD503>
<TD504>M</TD504>
</ns0:TD5>
<ns0:TD3>
<TD301>TL</TD301>
<TD309>TRL0000590</TD309>
</ns0:TD3>
<ns0:REF>
<REF01>SN</REF01>
<REF02>SEAL082401</REF02>
</ns0:REF>
<ns0:REF>
<REF01>BM</REF01>
<REF02>10401217</REF02>
</ns0:REF>
<ns0:DTM_2>
<DTM01>011</DTM01>
<DTM02>20160819</DTM02>
</ns0:DTM_2>
<ns0:N1Loop1>
<ns0:N1>
<N101>SF</N101>
<N102>any name</N102>
<N103>92</N103>
<N104>61</N104>
</ns0:N1>
<ns0:N3>
<N301>101 Your WAY</N301>
</ns0:N3>
<ns0:N4>
<N401>Irvine</N401>
<N402>CA</N402>
<N403>91111</N403>
<N404>USA</N404>
</ns0:N4>
</ns0:N1Loop1>
<ns0:N1Loop1>
<ns0:N1>
<N101>ST</N101>
<N102>0010</N102>
<N103>92</N103>
<N104>0010</N104>
</ns0:N1>
<ns0:N3>
<N301>1234 My Way Ct</N301>
</ns0:N3>
<ns0:N4>
<N401>GROVEPORT</N401>
<N402>OH</N402>
<N403>43125</N403>
<N404>USA</N404>
</ns0:N4>
</ns0:N1Loop1>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>2</HL01>
<HL03>O</HL03>
</ns0:HL>
<ns0:PRF>
<PRF01>10401217</PRF01>
<PRF04>20160822</PRF04>
<PRF06>10401217</PRF06>
<PRF07>KN</PRF07>
</ns0:PRF>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>3</HL01>
<HL03>T</HL03>
</ns0:HL>
<ns0:MAN>
<MAN01>GM</MAN01>
<MAN02>L000000000T5</MAN02>
</ns0:MAN>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>4</HL01>
<HL03>I</HL03>
</ns0:HL>
<ns0:LIN>
<LIN01>20000</LIN01>
<LIN02>UP</LIN02>
<LIN03>030111169051</LIN03>
<LIN04>VN</LIN04>
<LIN05>416905</LIN05>
<LIN10>RU</LIN10>
<LIN11>20180614</LIN11>
</ns0:LIN>
<ns0:SN1>
<SN102>32</SN102>
<SN103>EA</SN103>
</ns0:SN1>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>5</HL01>
<HL03>T</HL03>
</ns0:HL>
<ns0:MAN>
<MAN01>GM</MAN01>
<MAN02>L000000000T6</MAN02>
</ns0:MAN>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>6</HL01>
<HL03>I</HL03>
</ns0:HL>
<ns0:LIN>
<LIN01>20000</LIN01>
<LIN02>UP</LIN02>
<LIN03>030111169051</LIN03>
<LIN04>VN</LIN04>
<LIN05>416905</LIN05>
<LIN10>RU</LIN10>
<LIN11>20180614</LIN11>
</ns0:LIN>
<ns0:SN1>
<SN102>32</SN102>
<SN103>EA</SN103>
</ns0:SN1>
</ns0:HLLoop1>
<ns0:CTT>
<CTT01>6</CTT01>
</ns0:CTT>
<SE>
<SE01>79</SE01>
<SE02>0001</SE02>
</SE>
</ns0:X12_00401_856>
当 HL03
= 'T'
时,您的 XSLT 仅输出 DTM
个节点,但您的输入文档只有 LIN/LIN11
,其中 HL03
是别的东西 (I
).
如果想在没有LIN11的情况下不输出DTM节点,可以这样:
<!--Pack-->
<xsl:if test="ns0:HL/HL03 = 'T'">
<xsl:element name="ns0:HLLoop1">
<xsl:element name="ns0:HL">
<xsl:element name="HL01">
<xsl:value-of select="userCSharp:ReturnHL01('T')" />
</xsl:element>
<xsl:element name="HL02">
<xsl:value-of select="userCSharp:ReturnHL02('O')" />
</xsl:element>
<xsl:element name="HL03">T</xsl:element>
</xsl:element>
<xsl:element name="ns0:MAN">
<xsl:element name="MAN01">GM</xsl:element>
<xsl:element name="MAN02">
<xsl:value-of select="ns0:MAN/MAN02" />
</xsl:element>
</xsl:element>
<!--End of MAN-->
<xsl:if test="ns0:LIN/LIN11">
<xsl:element name="ns0:DTM_2">
<xsl:element name="DTM01">036</xsl:element>
<xsl:element name="DTM02">
<xsl:value-of select="ns0:LIN/LIN11"/>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:element>
<!--End of HLLoop1 Pack-->
</xsl:if>
如果你需要下面的LIN11
节点,你可以使用这样的代码:
<xsl:element name="DTM02">
<xsl:value-of select="following::LIN11[1]"/>
</xsl:element>
但这似乎很可疑并且容易被破坏(如果没有跟随 LIN11 怎么办,如果它是 10 个 HL 循环并被多次重复使用怎么办,等等...)。您可能最好获得具有 HL03 = 'I'
的 following
HL 循环,也许使用类似此处 XSLT: Loop selecting two elements at a time