XML 使用 xslt 时丢弃的元素标签

XML element tags discarded while using xslt

输入xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:orderMessageRequest xmlns:ns2="http://order.com.company.com">
<ns2:orderAck><orderNumber>25</orderNumber>
</ns2:orderAck>
</ns2:orderMessageRequest>

xslt 看起来像:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns2="http://www.company.com/services/entity/v1"
                xmlns:ns3="http://www.company.com/services/dataobject/v1"
                 xmlns:ns4="http://order.com.company.com/">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="orderAck">
        <xsl:element name="orderAcknowledgement" >
            <xsl:element name="orderNumber"><xsl:value-of select="orderNumber"/></xsl:element>
        </xsl:element>
    </xsl:template>

我在上面显示的 xml 上使用 xslt 转换然后它转换没有 xml 元素,直接值没有元素标签,比如。

<?xml version="1.0" encoding="UTF-8"?>25

如何获得 xml 格式的文件?如下所示:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns2:orderAcknowledgement      xmlns:ns2="http://www.company.com/services/dataobject/v1">   

<orderNumber>25</orderNumber>
    </ns2:orderAcknowledgement>

在您的输入 XML 中,orderAck 是命名空间 http://order.com.company.com 的一部分。但是,如评论中所述,在您的 XSLT 中,您目前正在寻找一个没有名称空间的元素 orderAck,这与名称空间中的元素不同。

现在,您应该可以做到这一点...

<xsl:template match="ns4:orderAck">

但这不匹配的原因不是因为前缀不同,而是因为附加到前缀的命名空间 URI 在您的 XSLT 中不同。在你的 XML 中是这个...

http://order.com.company.com

但在您的 XSLT 中是这样的

http://order.com.company.com/

最后的/让他们与众不同。 (它们是 URI,而不是 URL)。

另请注意,当您使用 xsl:element 创建 orderAcknowledgement 时,您也没有指定命名空间,因此您不会获得所需的输出,因为您确实需要 orderAcknowledgement 在命名空间中。

试试这个 XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns2="http://www.company.com/services/entity/v1"
                xmlns:ns3="http://www.company.com/services/dataobject/v1"
                 xmlns:ns4="http://order.com.company.com">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="ns4:orderAck">
        <xsl:element name="ns3:orderAcknowledgement" >
            <xsl:element name="orderNumber"><xsl:value-of select="orderNumber"/></xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

再次注意,重要的是 URI,而不是前缀。 orderAcknowledgement 根据需要位于命名空间 http://www.company.com/services/dataobject/v1 中。如果你真的想要 ns2 你可以改变前缀。另请注意,在这些情况下您实际上不需要使用 xsl:element 。照常写出元素即可。

也试试这个 XSLT...

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns3="http://www.company.com/services/entity/v1"
                xmlns:ns2="http://www.company.com/services/dataobject/v1"
                xmlns:ns4="http://order.com.company.com"
                exclude-result-prefixes="ns3 ns4">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="ns4:orderAck">
        <ns2:orderAcknowledgement>
            <orderNumber><xsl:value-of select="orderNumber"/></orderNumber>
        </ns2:orderAcknowledgement>
    </xsl:template>
</xsl:stylesheet>

请仔细阅读命名空间。例如尝试 http://www.xml.com/pub/a/1999/01/namespaces.html and http://www.xml.com/pub/a/2001/04/04/trxml/index.html.

您已经犯了两个最常见的 XSLT 初学者错误并将它们结合起来。

首先,您忽略了输入元素位于命名空间中这一事实,除非您使用前缀限定元素名称,否则它们将不匹配样式表中的模板规则或路径表达式。

其次,您忽略了如果没有匹配元素的模板规则,默认规则就会生效,默认规则会沿着树向下工作到文本节点,然后输出文本节点。