如何使用XSLT在添加子节点时转换XML?

如何使用XSLT在添加子节点时转换XML?,xml,xslt,Xml,Xslt,我将以下XML文档作为Java程序的输入(InputXML),该程序应用XSL(TransformationXSL)将其转换为输出XML(OutputXML) 我想添加一个额外的节点,作为输入XML转换的一部分。有没有比(transformationxsl)中显示的更好的方法,因为这只是尝试匹配元素并复制所需内容???如有其他有效的方法/建议,我们将不胜感激 输入XML <?xml version="1.0" encoding="UTF-8"?> <tuple>

我将以下XML文档作为Java程序的输入(InputXML),该程序应用XSL(TransformationXSL)将其转换为输出XML(OutputXML

我想添加一个额外的节点,作为输入XML转换的一部分。有没有比(transformationxsl)中显示的更好的方法,因为这只是尝试匹配元素并复制所需内容???如有其他有效的方法/建议,我们将不胜感激

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<tuple>
    <old>
        <Customers>
            <OrderID>10248</OrderID>
            <CustomerID>VINET</CustomerID>
            <EmployeeID>8</EmployeeID>
            <OrderDate>1996-07-04T00:00:00.0</OrderDate>
            <CustomerID>VINET</CustomerID>
            <CompanyName>Vins et alcools Chevalier</CompanyName>
        </Customers>
    </old>
</tuple>
<?xml version="1.0" encoding="UTF-8"?>
<tuple>
    <old>
        <Customers>
            <Orders>
                <OrderID>10248</OrderID>
                <CustomerID>VINET</CustomerID>
                <EmployeeID>8</EmployeeID>
                <OrderDate>1996-07-04T00:00:00.0</OrderDate>
            </Orders>
            <CustomerID>VINET</CustomerID>
            <CompanyName>Vins et alcools Chevalier</CompanyName>                
        </Customers>
    </old>
</tuple>

10248
葡萄藤
8.
1996-07-04T00:00:00.0
葡萄藤
酒与酒骑士
OutputXML

<?xml version="1.0" encoding="UTF-8"?>
<tuple>
    <old>
        <Customers>
            <OrderID>10248</OrderID>
            <CustomerID>VINET</CustomerID>
            <EmployeeID>8</EmployeeID>
            <OrderDate>1996-07-04T00:00:00.0</OrderDate>
            <CustomerID>VINET</CustomerID>
            <CompanyName>Vins et alcools Chevalier</CompanyName>
        </Customers>
    </old>
</tuple>
<?xml version="1.0" encoding="UTF-8"?>
<tuple>
    <old>
        <Customers>
            <Orders>
                <OrderID>10248</OrderID>
                <CustomerID>VINET</CustomerID>
                <EmployeeID>8</EmployeeID>
                <OrderDate>1996-07-04T00:00:00.0</OrderDate>
            </Orders>
            <CustomerID>VINET</CustomerID>
            <CompanyName>Vins et alcools Chevalier</CompanyName>                
        </Customers>
    </old>
</tuple>

10248
葡萄藤
8.
1996-07-04T00:00:00.0
葡萄藤
酒与酒骑士
这就是我所说的转换xsl。是否可以对其进行修改,以有效地转换输入XML,从而生成所需的输出XML

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

    <xsl:strip-space elements="*" />
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Customers">
        <Customers>
            <Orders>
                <OrderID>10248</OrderID>
                <CustomerID>VINET</CustomerID>
                <EmployeeID>8</EmployeeID>
                <OrderDate>1996-07-04T00:00:00.0</OrderDate>
            </Orders>
            <CustomerID>VINET</CustomerID>
            <CompanyName>Vins et alcools Chevalier</CompanyName>
        </Customers>
    </xsl:template>
</xsl:stylesheet>

10248
葡萄藤
8.
1996-07-04T00:00:00.0
葡萄藤
酒与酒骑士

如果InputXML中的双标记
CustomerID
是一个错误,请检查下面的解决方案

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

    <xsl:output method="xml"
                version="1.0"
                encoding="utf-8"
                indent="yes"
                standalone="yes"
                omit-xml-declaration="no"/>

    <xsl:strip-space elements="*" />
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="OrderID">
        <xsl:element name="Orders">
            <xsl:element name="OrderID">
                <xsl:value-of select="../OrderID/text()"/>
            </xsl:element>
            <xsl:element name="CustomerID">
                <xsl:value-of select="../CustomerID/text()"/>
            </xsl:element>
            <xsl:element name="EmployeeID">
                <xsl:value-of select="../EmployeeID/text()"/>
            </xsl:element>
            <xsl:element name="OrderDate">
                <xsl:value-of select="../OrderDate/text()"/>
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="EmployeeID"/>
    <xsl:template match="OrderDate"/>
</xsl:stylesheet>

如果InputXML中的双标记
CustomerID
是一个错误,请检查下面的解决方案

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

    <xsl:output method="xml"
                version="1.0"
                encoding="utf-8"
                indent="yes"
                standalone="yes"
                omit-xml-declaration="no"/>

    <xsl:strip-space elements="*" />
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="OrderID">
        <xsl:element name="Orders">
            <xsl:element name="OrderID">
                <xsl:value-of select="../OrderID/text()"/>
            </xsl:element>
            <xsl:element name="CustomerID">
                <xsl:value-of select="../CustomerID/text()"/>
            </xsl:element>
            <xsl:element name="EmployeeID">
                <xsl:value-of select="../EmployeeID/text()"/>
            </xsl:element>
            <xsl:element name="OrderDate">
                <xsl:value-of select="../OrderDate/text()"/>
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="EmployeeID"/>
    <xsl:template match="OrderDate"/>
</xsl:stylesheet>

您可以通过以下方式轻松获得显示的输出:

XSLT1.0

<xsl:stylesheet version="1.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="Customers">
    <xsl:copy>
        <Orders>
            <xsl:copy-of select="OrderID | CustomerID[1] | EmployeeID | OrderDate"/>
        </Orders>
        <xsl:copy-of select="CustomerID[1] | CompanyName"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

您可以通过以下方式轻松获得显示的输出:

XSLT1.0

<xsl:stylesheet version="1.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="Customers">
    <xsl:copy>
        <Orders>
            <xsl:copy-of select="OrderID | CustomerID[1] | EmployeeID | OrderDate"/>
        </Orders>
        <xsl:copy-of select="CustomerID[1] | CompanyName"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>


将订单中的少数元素分组后的逻辑是什么?逻辑上的区别在于,订单表(NORTHWIND数据库,MS SQL Server)中的列要放在订单标记下,其余元素是客户表中的列。XSLT对我来说毫无意义:为什么要硬编码这些值?--至于这样一个问题:是否总是只有一条记录,包含一个订单和一个客户?我很尴尬地提出了一个XSL,就像我分享的那样,但为了实现所需的输出,我没有找到更好的解决方案。感谢@Alexey,我有一个!要回答问题,是的,总是一个订单和一个客户。在
Orders
中分组少数元素的逻辑是什么?逻辑上的区别在于,Orders表(NORTHWIND database,MS SQL Server)中的列被置于Orders标记下,其余的元素都是Customers表中的列。我觉得XSLT毫无意义:为什么要硬编码这些值?--至于这样一个问题:是否总是只有一条记录,包含一个订单和一个客户?我很尴尬地提出了一个XSL,就像我分享的那样,但为了实现所需的输出,我没有找到更好的解决方案。感谢@Alexey,我有一个!回答您的问题,是的,总是一个订单和一个客户。谢谢分享。如果
Customers
标签和
Orders
标签下都需要CustomerID,该怎么办?是否可以采取措施使
客户
下只有一个元素?(现在重复两次!)谢谢分享。如果
Customers
标签和
Orders
标签下都需要CustomerID,该怎么办?是否可以采取措施使
客户
下只有一个元素?(现在重复了两次!)