【问题标题】:XSLT: Find the way to transform to XMLXSLT:找到转换为 XML 的方法
【发布时间】:2021-04-06 09:35:04
【问题描述】:

我有以下格式的 XML:

     <?xml version="1.0"?>
<MES_VEHICLE_STATUS_DESCRIPTOR xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="MOM.Production"  PRODUCTIONORDER="000001995795" >
  <POSECTION LOCATION="" />
  <ORDERSECTION SALESORDER=""  />
  <MATERIALCONSUMPTIONSECTION>
    <MATERIAL_CONSUMPTION DESC="car" QTY="1.000" WORKPLACE="3001_GAT101LH">BIN1000004</MATERIAL_CONSUMPTION>
    <MATERIAL_CONSUMPTION DESC="PLAIN_WASHER" QTY="1.000" WORKPLACE="3001_GAT101LH">WRE20000018</MATERIAL_CONSUMPTION>
    <MATERIAL_CONSUMPTION DESC="car" QTY="1.000" WORKPLACE="3001_GAT101LH">BIN1000003</MATERIAL_CONSUMPTION>
    
  </MATERIALCONSUMPTIONSECTION>
</MES_VEHICLE_STATUS_DESCRIPTOR>

输出应该是这样的:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:mat="http://mes.com/ScrapManagement">
   <soapenv:Header/>
   <soapenv:Body>
      <mat:DT_SCRAPMANAGEMENT_MES_REQ>
         <DATA>
            <PlantCode>3002</PlantCode>
            <SAPOrder>000001995795</SAPOrder>
            <Quantity>1.000</Quantity>
            <PartNo>BIN1000004</PartNo>
            <WorkPlace>3001_GAT101LH</WorkPlace>
         </DATA>
         <DATA>
            <PlantCode>3002</PlantCode>
            <SAPOrder>000001995795</SAPOrder>
            <Quantity>1.000</Quantity>
            <PartNo>WRE20000018</PartNo>
            <WorkPlace>3001_GAT101LH</WorkPlace>
         </DATA>
         <DATA>
            <PlantCode>3002</PlantCode>
            <SAPOrder>000001995795</SAPOrder>
            <Quantity>1.000</Quantity>
            <PartNo>BIN1000003</PartNo>
            <WorkPlace>3001_GAT101LH</WorkPlace>
         </DATA>
                     
      </mat:DT_SCRAPMANAGEMENT_MES_REQ>
   </soapenv:Body>
</soapenv:Envelope>

我要转换的 XSLT

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >
    <xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0" />
    <xsl:template match="MES_VEHICLE_STATUS_DESCRIPTOR">
        <soapenv:Envelope
            xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:mat="http://mes.com/ScrapManagement">
            <soapenv:Header />
            <soapenv:Body>
                <xsl:element name="mat:DT_SCRAPMANAGEMENT_MES_REQ">
                    <xsl:variable name="po" select="@PRODUCTIONORDER" />
                    <xsl:for-each select="MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION">
                        <DATA>
                            <PlantCode>
                                <xsl:text>3002</xsl:text>
                            </PlantCode>
                            <SAPOrder>
                                <xsl:value-of select="$po" />
                            </SAPOrder>
                            <Quantity>
                                <xsl:value-of select="@QTY" />
                            </Quantity>
                            <PartNo>
                                <xsl:value-of select="." />
                            </PartNo>
                            <WorkPlace>
                                <xsl:value-of select="@WORKPLACE" />
                            </WorkPlace>
                        </DATA>
                    </xsl:for-each>
                </xsl:element>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>
</xsl:stylesheet>

如果我在 XML 文件中删除 xmlns="MOM.Production",则转换是可以的。但如果在 xml 文件中有它,则无法转换。我使用网站:https://www.online-toolz.com/tools/xslt-transformation.php 并显示错误:Error:DOMDocument::loadXML(): xmlns: URI MOM.Production is not absolute in Entity, line: 2。 我不明白什么是理由。 不明白是什么原因

【问题讨论】:

标签: xslt


【解决方案1】:

您脑海中的代码可能或多或少是这样的:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0" />

  <xsl:template match="MES_VEHICLE_STATUS_DESCRIPTOR">
    <xsl:for-each select="MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION">
      <xsl:element name="DATA">
        <xsl:element name="PRODUCTIONORDER">
          <xsl:value-of select="../../@PRODUCTIONORDER" />
        </xsl:element>
        <xsl:element name="QTY">
          <xsl:value-of select="@QTY" />
        </xsl:element>
        <xsl:element name="MATERIAL">
          <xsl:value-of select="text()" />
        </xsl:element>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

我认为您必须了解用于选择正确节点的 XPATH 表达式中相对路径和绝对路径之间的区别。

当您位于与节点 MES_VEHICLE_STATUS_DESCRIPTOR 匹配的模板中时,您不会使用像 /MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION 这样的绝对路径(在这种情况下不存在),而是使用相对于该节点的路径,如 MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION

当您在&lt;xsl:for-each select="MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION"&gt; 循环中时,您必须选择具有相对路径的节点,例如text()../../@PRODUCTIONORDER@QTY。注意 @ 告诉 QTY 和 PRODUCTIONORDER 是属性类型节点。

最后,您当前的输出不是格式良好的 XML,因为它缺少根元素。

个人而言,我会用它的字面值替换&lt;xsl:element&gt; 标签,并避免计算循环中的常量字段:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0" />

  <xsl:template match="MES_VEHICLE_STATUS_DESCRIPTOR">
    <xsl:variable name="po" select="@PRODUCTIONORDER" />
    <xsl:for-each select="MATERIALCONSUMPTIONSECTION/MATERIAL_CONSUMPTION">
      <DATA>
        <PRODUCTIONORDER><xsl:value-of select="$po" /></PRODUCTIONORDER>
        <QTY><xsl:value-of select="@QTY" /></QTY>
        <MATERIAL><xsl:value-of select="." /></MATERIAL>
      </DATA>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

【讨论】:

  • 使用文字结果元素代替xsl:element。还可以考虑为 PRODUCTIONORDER 使用变量,而不是从祖先节点重复查找。
  • @michael.hor257k 我完全同意你的看法。在这种情况下,我想做最小的更改以使 PO 的代码正常工作。我将在上面编辑我的解决方案。
  • 还有一个:使用&lt;xsl:variable name="po" select="@PRODUCTIONORDER"/&gt;,而不是在变量内创建文本节点。
  • @michael.hor257k:我再次同意。
  • @michael.hor257k 为什么不选择&lt;MATERIAL&gt;&lt;xsl:value-of select="." /&gt;&lt;/MATERIAL&gt; 而不是选择text()...
猜你喜欢
  • 2020-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 2017-06-02
相关资源
最近更新 更多