XSLT:检查空元素是否为空然后只将值赋给其他元素的条件
XSLT :Condition for check if null and empty element then only assign value to other element
我们输入 XML.In,StockCode 元素对于许多订单项(OrderLineID 元素)为空。对于 XML 中的所有空 StockCode 元素,必须有 Comment 元素值。同样,对于所有此类空 Comment 元素,必须存在 StockCode 值。
注意 :
OrderDetail 在这里重复节点。
场景:
我们必须拆分 OrderDescription 字符串。这样它总是寻找空的 StockCode 元素。然后仅将拆分字符串值分配给 Comment 元素。否则,对于所有具有值的 StockCode,不应将拆分字符串分配给 Comment Element
输入 XML :
<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
<Orders>
<OrderHeader>
<Customer>000016</Customer>
<OrderDate>2016-04-19</OrderDate>
<SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
</OrderHeader>
<OrderDetails>
<StockLine>
<StockCode>ABB-CDE-FGH-01</StockCode>
<OrderDescription>EDIORDER-SAVE COMMENTS
C3 Generic
LOC 0833
Expected arrival 01/07/2016
OTYPE NE
TRKPC 01 GM/00007643020008361321</OrderDescription>
<OrderLineID>OR-1561179</OrderLineID>
</StockLine>
<StockLine>
<StockCode>BCD-EFGH-01</StockCode>
<OrderLineID>OR-1561186</OrderLineID>
</Comment>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561180</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561181</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561182</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561183</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561184</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561185</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
用于转换的现有 XSLT:
XSLT2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="StockLine">
<xsl:variable name="i" select="position()" />
<xsl:copy>
<xsl:copy-of select="StockCode"/>
<Comment>
<xsl:value-of select="normalize-space(tokenize(../StockLine[1]/OrderDescription, '\n')[$i])"/>
</Comment>
<xsl:copy-of select="OrderLineID"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
预期输出值:
<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
<Orders>
<OrderHeader>
<Customer>000016</Customer>
<OrderDate>2016-04-19</OrderDate>
<SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
</OrderHeader>
<OrderDetails>
<StockLine>
<StockCode>ABB-CDE-FGH-01</StockCode>
</Comment>
<OrderDescription>EDIORDER-SAVE COMMENTS
C3 Generic
LOC 0833
Expected arrival 01/07/2016
OTYPE NE
TRKPC 01 GM/00007643020008361321</OrderDescription>
<OrderLineID>OR-1561179</OrderLineID>
</StockLine>
<StockLine>
<StockCode>BCD-EFGH-01</StockCode>
<OrderLineID>OR-1561186</OrderLineID>
</Comment>
</StockLine>
<StockLine>
<Comment>EDIORDER-SAVE COMMENTS</Comment>
</StockCode>
<OrderLineID>OR-1561180</OrderLineID>
</StockLine>
<StockLine>
<Comment>C3 Generic</Comment>
</StockCode>
<OrderLineID>OR-1561181</OrderLineID>
</StockLine>
<StockLine>
<Comment>LOC 0833</Comment>
</StockCode>
<OrderLineID>OR-1561182</OrderLineID>
</StockLine>
<StockLine>
<Comment>Expected arrival 01/07/2016</Comment>
</StockCode>
<OrderLineID>OR-1561183</OrderLineID>
</StockLine>
<StockLine>
<Comment> OTYPE NE</Comment>
</StockCode>
<OrderLineID>OR-1561184</OrderLineID>
</StockLine>
<StockLine>
<Comment>TRKPC 01 GM/00007643020008361321</Comment>
</StockCode>
<OrderLineID>OR-1561185</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
要转换示例输入,您只需像这样在 StockCode 节点上进行模板匹配:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="StockCode[not(node())]">
<xsl:variable name="i"><xsl:number count="StockCode[not(node())]" select="../StockCode[not(node())]" level="any" /></xsl:variable>
<xsl:copy>
<xsl:value-of select="normalize-space(tokenize(ancestor::OrderDetails/StockLine[1]/OrderDescription, '\n')[number($i)])"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
该模板将只适用于没有内容的股票代码。由于这是唯一的模板,所有其他节点在输出中将保持不变(由于身份模板)。
匹配模板将计算所有先前为空的 StockCode 节点,并将其用作索引来定位描述的标记化文本。
这是我的建议,标记一次并将值作为参数传递:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OrderDetails">
<xsl:copy>
<xsl:variable name="descriptions" as="xs:string*" select="tokenize(StockLine[1]/OrderDescription, '\n')"/>
<xsl:apply-templates>
<xsl:with-param name="descriptions" as="xs:string*" select="$descriptions" tunnel="yes"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="StockLine/StockCode[not(normalize-space())]">
<xsl:param name="descriptions" tunnel="yes"/>
<xsl:variable name="pos" as="xs:integer">
<xsl:number count="StockLine[StockCode[not(normalize-space())]]"/>
</xsl:variable>
<xsl:copy>
<xsl:value-of select="normalize-space($descriptions[$pos])"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果您想创建新的 Comment
元素而不是填充空 StockCode
元素,请使用如下方法:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OrderDetails">
<xsl:copy>
<xsl:variable name="descriptions" as="xs:string*" select="tokenize(StockLine[1]/OrderDescription, '\n')"/>
<xsl:apply-templates>
<xsl:with-param name="descriptions" as="xs:string*" select="$descriptions"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="StockLine[StockCode[not(normalize-space())]]">
<xsl:param name="descriptions"/>
<xsl:variable name="pos" as="xs:integer">
<xsl:number count="StockLine[StockCode[not(normalize-space())]]"/>
</xsl:variable>
<xsl:copy>
<xsl:copy-of select="*"/>
<Comment><xsl:value-of select="normalize-space($descriptions[$pos])"/></Comment>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我们输入 XML.In,StockCode 元素对于许多订单项(OrderLineID 元素)为空。对于 XML 中的所有空 StockCode 元素,必须有 Comment 元素值。同样,对于所有此类空 Comment 元素,必须存在 StockCode 值。
注意 : OrderDetail 在这里重复节点。
场景:
我们必须拆分 OrderDescription 字符串。这样它总是寻找空的 StockCode 元素。然后仅将拆分字符串值分配给 Comment 元素。否则,对于所有具有值的 StockCode,不应将拆分字符串分配给 Comment Element
输入 XML :
<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
<Orders>
<OrderHeader>
<Customer>000016</Customer>
<OrderDate>2016-04-19</OrderDate>
<SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
</OrderHeader>
<OrderDetails>
<StockLine>
<StockCode>ABB-CDE-FGH-01</StockCode>
<OrderDescription>EDIORDER-SAVE COMMENTS
C3 Generic
LOC 0833
Expected arrival 01/07/2016
OTYPE NE
TRKPC 01 GM/00007643020008361321</OrderDescription>
<OrderLineID>OR-1561179</OrderLineID>
</StockLine>
<StockLine>
<StockCode>BCD-EFGH-01</StockCode>
<OrderLineID>OR-1561186</OrderLineID>
</Comment>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561180</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561181</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561182</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561183</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561184</OrderLineID>
</StockLine>
<StockLine>
<StockCode></StockCode>
</Comment>
<OrderLineID>OR-1561185</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
用于转换的现有 XSLT:
XSLT2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="StockLine">
<xsl:variable name="i" select="position()" />
<xsl:copy>
<xsl:copy-of select="StockCode"/>
<Comment>
<xsl:value-of select="normalize-space(tokenize(../StockLine[1]/OrderDescription, '\n')[$i])"/>
</Comment>
<xsl:copy-of select="OrderLineID"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
预期输出值:
<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
<Orders>
<OrderHeader>
<Customer>000016</Customer>
<OrderDate>2016-04-19</OrderDate>
<SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
</OrderHeader>
<OrderDetails>
<StockLine>
<StockCode>ABB-CDE-FGH-01</StockCode>
</Comment>
<OrderDescription>EDIORDER-SAVE COMMENTS
C3 Generic
LOC 0833
Expected arrival 01/07/2016
OTYPE NE
TRKPC 01 GM/00007643020008361321</OrderDescription>
<OrderLineID>OR-1561179</OrderLineID>
</StockLine>
<StockLine>
<StockCode>BCD-EFGH-01</StockCode>
<OrderLineID>OR-1561186</OrderLineID>
</Comment>
</StockLine>
<StockLine>
<Comment>EDIORDER-SAVE COMMENTS</Comment>
</StockCode>
<OrderLineID>OR-1561180</OrderLineID>
</StockLine>
<StockLine>
<Comment>C3 Generic</Comment>
</StockCode>
<OrderLineID>OR-1561181</OrderLineID>
</StockLine>
<StockLine>
<Comment>LOC 0833</Comment>
</StockCode>
<OrderLineID>OR-1561182</OrderLineID>
</StockLine>
<StockLine>
<Comment>Expected arrival 01/07/2016</Comment>
</StockCode>
<OrderLineID>OR-1561183</OrderLineID>
</StockLine>
<StockLine>
<Comment> OTYPE NE</Comment>
</StockCode>
<OrderLineID>OR-1561184</OrderLineID>
</StockLine>
<StockLine>
<Comment>TRKPC 01 GM/00007643020008361321</Comment>
</StockCode>
<OrderLineID>OR-1561185</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
要转换示例输入,您只需像这样在 StockCode 节点上进行模板匹配:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="StockCode[not(node())]">
<xsl:variable name="i"><xsl:number count="StockCode[not(node())]" select="../StockCode[not(node())]" level="any" /></xsl:variable>
<xsl:copy>
<xsl:value-of select="normalize-space(tokenize(ancestor::OrderDetails/StockLine[1]/OrderDescription, '\n')[number($i)])"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
该模板将只适用于没有内容的股票代码。由于这是唯一的模板,所有其他节点在输出中将保持不变(由于身份模板)。 匹配模板将计算所有先前为空的 StockCode 节点,并将其用作索引来定位描述的标记化文本。
这是我的建议,标记一次并将值作为参数传递:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OrderDetails">
<xsl:copy>
<xsl:variable name="descriptions" as="xs:string*" select="tokenize(StockLine[1]/OrderDescription, '\n')"/>
<xsl:apply-templates>
<xsl:with-param name="descriptions" as="xs:string*" select="$descriptions" tunnel="yes"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="StockLine/StockCode[not(normalize-space())]">
<xsl:param name="descriptions" tunnel="yes"/>
<xsl:variable name="pos" as="xs:integer">
<xsl:number count="StockLine[StockCode[not(normalize-space())]]"/>
</xsl:variable>
<xsl:copy>
<xsl:value-of select="normalize-space($descriptions[$pos])"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果您想创建新的 Comment
元素而不是填充空 StockCode
元素,请使用如下方法:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OrderDetails">
<xsl:copy>
<xsl:variable name="descriptions" as="xs:string*" select="tokenize(StockLine[1]/OrderDescription, '\n')"/>
<xsl:apply-templates>
<xsl:with-param name="descriptions" as="xs:string*" select="$descriptions"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="StockLine[StockCode[not(normalize-space())]]">
<xsl:param name="descriptions"/>
<xsl:variable name="pos" as="xs:integer">
<xsl:number count="StockLine[StockCode[not(normalize-space())]]"/>
</xsl:variable>
<xsl:copy>
<xsl:copy-of select="*"/>
<Comment><xsl:value-of select="normalize-space($descriptions[$pos])"/></Comment>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>