【问题标题】:Merge two XSLT into one to process the same nodes for two different reasons出于两个不同的原因将两个 XSLT 合并为一个以处理相同的节点
【发布时间】:2017-11-16 16:31:37
【问题描述】:

我想删除所有命名空间(包括属性中的所有 xmlns 和 xsi),然后想对输出进行排序。

示例 XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="https://www.w3schools.com/furniture" xmlns='http://ns.xyz.org/2004-08-02'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:ns1='http://ns.xyz.org/2004-08-02'
xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:type='ns1:table'>

    <h:table>
        <h:tr>
            <!-- <TestComment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/> -->
            <h:td att2="2" att1="1">Bananas</h:td>
            <h:td xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true">Apples</h:td>
        </h:tr>
    </h:table>

    <f:table>
        <f:name class="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true">African Coffee Table</f:name>
        <f:width>80</f:width>
        <f:length>120</f:length>
    </f:table>
</root>

现在我正在将 xml 转换为两个不同的 xsls。

XSL 删除命名空间(包括 xmlns 和 xsi)是

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@xsi:*" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<xsl:template match="comment()|processing-instruction()"/>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
        <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>

这给了我以下输出

<root>
    <table>
        <tr>
            <td att2="2" att1="1">Bananas</td>
            <td>Apples</td>
        </tr>
    </table>
    <table>
        <name class="1">African Coffee Table</name>
        <width>80</width>
        <length>120</length>
    </table>
</root>

然后我使用下面的 xsl 对 xml 进行排序

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output encoding="utf-8" method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*">
                <xsl:sort select="local-name()"/>
            </xsl:apply-templates>
            <xsl:apply-templates select="node()">
                <xsl:sort select="local-name()"/>
                <xsl:sort select="."/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这给了我最终的输出

<root>
    <table>
        <length>120</length>
        <name class="1">African Coffee Table</name>
        <width>80</width>
    </table>
    <table>
        <tr>
            <td>Apples</td>
            <td att1="1" att2="2">Bananas</td>
        </tr>
    </table>
</root>

现在,如何将这两个处理合并到一个 xsl 文件中,这样我就不必转换两次了?

【问题讨论】:

    标签: xml xslt xml-parsing xslt-1.0


    【解决方案1】:

    将两个xsl:sort 移入命名空间删除模板:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output encoding="utf-8" method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="@xsi:*" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
    <xsl:template match="comment()|processing-instruction()"/>
    
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@*">
                <xsl:sort select="local-name()"/>
            </xsl:apply-templates>
            <xsl:apply-templates>
              <xsl:sort select="local-name()"/>
              <xsl:sort select="."/>
            </xsl:apply-templates>
        </xsl:element>
    </xsl:template>
    
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    
    </xsl:stylesheet>
    

    http://xsltransform.hikmatu.com/jyyiVhg

    或者使用两种模式将处理步骤分开并在变量中执行第一步,然后使用exsl:node-set以第二步/模式进行处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多