我想根据某些条件输出xml。
这是我的输入XML
<YIORDER01>
<IDOC>
<E1ORHDR>
<E1OROPR>
<VORNR>0010</VORNR>
<E1OROPR_MAT>
<MATNR>M0003-01</MATNR>
<YE1OROPR_MAT>
<STTXT>REL</STTXT>
<MTART>ZPAR</MTART>
<POSTP>L</POSTP>
</YE1OROPR_MAT>
</E1OROPR_MAT>
<E1OROPR_MAT>
<MATNR>M0003-01</MATNR>
<YE1OROPR_MAT>
<STTXT>REL</STTXT>
<MTART>XYZ</MTART>
<POSTP>M</POSTP>
</YE1OROPR_MAT>
</E1OROPR_MAT>
</E1OROPR>
<E1OROPR>
<VORNR>0020</VORNR>
<E1OROPR_MAT>
<MATNR>M0003-01</MATNR>
<YE1OROPR_MAT>
<STTXT>REL</STTXT>
<MTART>ZPAR</MTART>
<POSTP>L</POSTP>
</YE1OROPR_MAT>
</E1OROPR_MAT>
</E1OROPR>
</E1ORHDR>
</IDOC>
</YIORDER01>
输出就是这样的。
<PartOrderList>
<PartOrder>
<OperationBONumber>0010</OperationBONumber>
<PartOrderLine>
<MaterialNumber>M0003-01</MaterialNumber>
<ShipmentType>REL</ShipmentType>
</PartOrderLine>
</PartOrder>
<PartOrder>
<OperationBONumber>0020</OperationBONumber>
</PartOrder>
</PartOrderList>
我的XSLT就是这个
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="YIORDER01">
<xsl:element name="PartOrderList">
<xsl:for-each select="IDOC/E1ORHDR/E1OROPR">
<xsl:element name="PartOrder">
<xsl:element name="OperationBONumber">
<xsl:value-of select="VORNR"/>
</xsl:element>
<xsl:for-each select="E1OROPR_MAT">
<xsl:if test="YE1OROPR_MAT/MTART = 'ZPAR' and YE1OROPR_MAT/POSTP = 'L'">
<xsl:element name="PartOrderLine">
<xsl:element name="MaterialNumber">
<xsl:value-of select="MATNR"/>
</xsl:element>
<xsl:element name="ShipmentType">
<xsl:value-of select="YE1OROPR_MAT/STTXT"/>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这里的问题是,我不想在输出中使用第二个“PartOrder”标记,因为它没有任何“PartOrderLine”子项。
xslt中使用的规则:
使用我的xslt我能够实现规则1和2,但不知道如何实现规则3 有什么方法可以使用xslt ??
实现这一点请帮忙。
答案 0 :(得分:3)
您需要将条件作为谓词添加到外部for-each
选择表达式中,以便您只知道 - 您知道的每个元素将生成至少一个PartOrderLine
<xsl:for-each select="IDOC/E1ORHDR/E1OROPR[
E1OROPR_MAT/YE1OROPR_MAT[MTART = 'ZPAR' and POSTP = 'L']]">
答案 1 :(得分:0)
仅供参考:这是我接近它的方式。这种方法的优点是:
。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<!-- Part Order List -->
<xsl:template match="/*">
<xsl:element name="PartOrderList">
<xsl:apply-templates select=".//E1OROPR" />
</xsl:element>
</xsl:template>
<!-- Part Order List > Part Order -->
<xsl:template match="//E1OROPR">
<xsl:variable name="IsValid">
<xsl:call-template name="HasOrIsValidPOLine" />
</xsl:variable>
<xsl:if test="$IsValid='VALID'"> <!-- only display the part order if there's a valid line under it-->
<xsl:element name="PartOrder">
<xsl:apply-templates select=".//VORNR" />
<xsl:apply-templates select=".//E1OROPR_MAT" />
</xsl:element>
</xsl:if>
</xsl:template>
<!-- Part Order List > Part Order > Operational BO Number -->
<xsl:template match="//VORNR">
<xsl:element name="OperationBONumber">
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:template>
<!-- Part Order List > Part Order > Part Order Line -->
<xsl:template match="//E1OROPR_MAT">
<xsl:variable name="IsValid">
<xsl:call-template name="HasOrIsValidPOLine" />
</xsl:variable>
<xsl:if test="$IsValid='VALID'">
<!-- only display the part order line if it's valid-->
<xsl:element name="PartOrderLine">
<xsl:apply-templates select=".//MATNR" />
<xsl:apply-templates select=".//STTXT" />
</xsl:element>
</xsl:if>
</xsl:template>
<!-- Part Order List > Part Order > Part Order Line > Material Number -->
<xsl:template match="//MATNR">
<xsl:element name="MaterialNumber">
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:template>
<!-- Part Order List > Part Order > Part Order Line > Shipment Type -->
<xsl:template match="//STTXT">
<xsl:element name="ShipmentType">
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:template>
<xsl:template name="HasOrIsValidPOLine">
<xsl:choose>
<xsl:when test=".//MTART/text() = 'ZPAR' and .//POSTP/text() = 'L'">VALID</xsl:when>
<xsl:otherwise>INVALID</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
那说可能有很多可以做的进一步改进/你选择哪个选项应该是你最熟悉的代码(在某种程度上;显然任何新的方法都有一个学习曲线可能引起初步不适,因此长期考虑应考虑到这一点。)