XSLT for-each替换元素名称中的文本

时间:2019-07-16 01:58:15

标签: xml xslt

我是XSLT的新手。我有一个已转换为XML的EDI文件

<?xml version="1.0" encoding="UTF-8"?>
<ns0:X12_00401_850 xmlns:ns0="....">
    .
    .
    .
   <ns0:PO1Loop1>
      <ns0:PO1>
         <PO101>000001</PO101>
         <PO102>1</PO102>
         <PO103>EA</PO103>
         <PO104>3531.65</PO104>
         <PO105>QT</PO105>
         <PO106>VP</PO106>
         <PO107>ACS5048-001</PO107>
         <PO108>BP</PO108>
         <PO109>Q90001</PO109>
      </ns0:PO1>
   </ns0:PO1Loop1>
   .
   .
   .
</ns0:X12_00401_850>

我正在尝试像这样为每个PO1节点创建一个ACK节点(如果有多个PO节点(即PO1,PO2,PO3等)为每个PO1节点创建一个ACK,那也很好。 / p>

      <ns0:PO1>
         <PO101>000001</PO101>
         <PO102>1</PO102>
         <PO103>EA</PO103>
         <PO104>3531.65</PO104>
         <PO105>QT</PO105>
         <PO106>VP</PO106>
         <PO107>ACS5048-001</PO107>
         <PO108>BP</PO108>
         <PO109>Q90001</PO109>
      </ns0:PO1>
      <ns0:ACK1>
         <ACK101>000001</ACK101>
         <ACK102>1</ACK102>
         <ACK103>EA</ACK103>
         <ACK104>3531.65</ACK104>
         <ACK105>QT</ACK105>
         <ACK106>VP</ACK106>
         <ACK107>ACS5048-001</ACK107>
         <ACK108>BP</ACK108>
         <ACK109>Q90001</ACK109>
      </ns0:ACK1>

我可以将ACK节点与PO1子节点的值相加,但是无法为每个节点创建一个节点。我只是不确定现在要去哪里创建节点并将子节点的名称从PO102更改为ACK2,将PO105更改为ACK5,等等。

这是我正在使用的XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns0="http://Citrix.EDI.Partners.IngramMicroUS.Schemas.850"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ns0:X12_00401_850">
        <ns0:X12_00401_855><xsl:apply-templates select="@*|node()" /></ns0:X12_00401_855>
    </xsl:template>

    <xsl:template match="ST01">
        <ST01>855</ST01>
    </xsl:template>

    <xsl:template match="ns0:PO1">
        <xsl:copy-of select="."/>
        <ns0:ACK1>
            <xsl:for-each select="./*">

            </xsl:for-each
        </ns0:ACK1>
    </xsl:template>    
</xsl:stylesheet>

预先感谢

1 个答案:

答案 0 :(得分:1)

这就是您需要的。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns0="http://Citrix.EDI.Partners.IngramMicroUS.Schemas.850"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ns0:X12_00401_850">
        <ns0:X12_00401_855>
            <xsl:apply-templates select="@*|node()" />
        </ns0:X12_00401_855>
    </xsl:template>

    <xsl:template match="ST01">
        <ST01>855</ST01>
    </xsl:template>

    <xsl:template match="ns0:PO1">
        <xsl:copy-of select="."/>
        <ns0:ACK1>
            <xsl:for-each select="./*">
                <xsl:variable name="ack_el" select="replace(local-name(), 'PO', 'ACK')"/>
                <xsl:element name="{$ack_el}">
                    <xsl:copy-of select="text()"/>
                </xsl:element>
            </xsl:for-each>
        </ns0:ACK1>
    </xsl:template>    
</xsl:stylesheet>

对于xslt 1.0。

使用

        <xsl:variable name="ack_el" select="concat('ACK', substring(local-name(), 3, string-length(local-name())))"/>