【问题标题】:Renaming root element and eliminating null values using XSLT使用 XSLT 重命名根元素并消除空值
【发布时间】:2016-03-21 05:15:20
【问题描述】:

我必须转换以下 xml 输入,

<Standards xmlns="http://ws.wso2.org/dataservice">
        <Standard>
            <ProductID>200057</ProductID>
            <Prefix>ISO</Prefix>
            <SNumber>1001</SNumber>
            <DraftProducts>
                <RelatedProduct>
                    <ProductID>1500163</ProductID>
                </RelatedProduct>
            </DraftProducts>
            <ReferenceProducts>
                <RelatedProduct>
                    <ProductID>263973</ProductID>
                    <RelationId>708519</RelationId>
                    <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                </RelatedProduct>
                <RelatedProduct>
                    <ProductID>320056</ProductID>
                    <RelationId>934789</RelationId>
                    <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                </RelatedProduct>
            </ReferenceProducts>
            <RelatedIntProducts>
                <RelatedProduct>
                    <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                    <RelationId>116881</RelationId>
                    <Relationship>Identical</Relationship>
                    <Designation>NEN ISO 1001</Designation>
                </RelatedProduct>
                <RelatedProduct>
                    <ProductID>208076</ProductID>
                    <RelationId>116886</RelationId>
                    <Relationship>Identical</Relationship>
                    <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                </RelatedProduct>
            </RelatedIntProducts>
            <S1>1001</S1>
            <S2>1986</S2>
        </Standard>
        <Standard>
            <ProductID>200058</ProductID>
            <Prefix>ISO</Prefix>
            <SNumber>1002</SNumber>
            <DraftProducts>
                <RelatedProduct>
                    <ProductID>1500167</ProductID>
                </RelatedProduct>
            </DraftProducts>
            <ReferenceProducts>
                <RelatedProduct>
                    <ProductID>263974</ProductID>
                    <RelationId>708519</RelationId>
                    <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                </RelatedProduct>
                <RelatedProduct>
                    <ProductID>320052</ProductID>
                    <RelationId>934754</RelationId>
                    <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                </RelatedProduct>
            </ReferenceProducts>
            <RelatedIntProducts>
                <RelatedProduct>
                    <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                    <RelationId>116837</RelationId>
                    <Relationship>Identical</Relationship>
                    <Designation>NEN ISO 1001</Designation>
                </RelatedProduct>
                <RelatedProduct>
                    <ProductID>208074</ProductID>
                    <RelationId>116843</RelationId>
                    <Relationship>Identical</Relationship>
                    <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                </RelatedProduct>
            </RelatedIntProducts>
            <S1>1005</S1>
            <S2>1983</S2>
        </Standard>
    </Standards>

转换成以下输出格式。

<Standards xmlns="http://ws.wso2.org/dataservice">
    <Product>
        <ProductID>200057</ProductID>
        <Prefix>ISO</Prefix>
        <SNumber>1001</SNumber>
        <RelatedProducts>
            <RelatedProduct>
                <ProductID>1500163</ProductID>
                <RelationType>DraftProducts</RelationType>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>263973</ProductID>
                <RelationId>708519</RelationId>
                <RelationType>ReferenceProducts</RelationType>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>320056</ProductID>
                <RelationId>934789</RelationId>
                <RelationType>ReferenceProducts</RelationType>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <RelationId>116881</RelationId>
                <Relationship>Identical</Relationship>
                <RelationType>RelatedIntProducts</RelationType>
                <Designation>NEN ISO 1001</Designation>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>208076</ProductID>
                <RelationId>116886</RelationId>
                <RelationType>RelatedIntProducts</RelationType>
                <Relationship>Identical</Relationship>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
        </RelatedProducts>
        <S1>1001</S1>
        <S2>1986</S2>
    </Product>
    <Product>
        <ProductID>200058</ProductID>
        <Prefix>ISO</Prefix>
        <SNumber>1002</SNumber>
        <RelatedProducts>
            <RelatedProduct>
                <ProductID>1500167</ProductID>
                <RelationType>DraftProducts</RelationType>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>263974</ProductID>
                <RelationId>708519</RelationId>
                <RelationType>ReferenceProducts</RelationType>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>320052</ProductID>
                <RelationId>934754</RelationId>
                <RelationType>ReferenceProducts</RelationType>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <RelationId>116837</RelationId>
                <RelationType>RelatedIntProducts</RelationType>
                <Relationship>Identical</Relationship>
                <Designation>NEN ISO 1001</Designation>
            </RelatedProduct>
            <RelatedProduct>
                <ProductID>208074</ProductID>
                <RelationId>116843</RelationId>
                <RelationType>RelatedIntProducts</RelationType>
                <Relationship>Identical</Relationship>
                <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
            </RelatedProduct>
        </RelatedProducts>
        <S1>1005</S1>
        <S2>1983</S2>
    </Product>
</Standards>

在其他人的帮助下,我可以编写以下 xslt 来进行这种转换。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:x="http://ws.wso2.org/dataservice" xmlns="http://ws.wso2.org/dataservice"
    exclude-result-prefixes="x" version="1.0">

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

    <!-- Identity Transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="x:Standard">
        <Product>
            <xsl:copy-of select="x:ProductID" />
            <xsl:copy-of select="x:Prefix" />
            <xsl:copy-of select="x:SNumber" />
            <xsl:copy-of select="x:Year" />
            <xsl:copy-of select="x:Designation" />
            <xsl:copy-of select="x:Publisher" />
            <RelatedProducts>
                <xsl:apply-templates select=".//x:RelatedProduct" />
            </RelatedProducts>
            <xsl:copy-of select="x:ProductICSCodes" />
            <xsl:copy-of select="x:ProductDescriptions" />
            <xsl:copy-of select="x:IndustryCodes" />
            <xsl:copy-of select="x:ProductAttributes" />
            <xsl:copy-of select="x:ProductReconfirmationNotices" />
            <xsl:copy-of select="x:Type" />
            <xsl:copy-of select="x:SaleItems" />
            <xsl:copy-of select="x:Committee" />
            <xsl:copy-of select="x:CommentClosesDate" />
            <xsl:copy-of select="x:Note" />
            <xsl:copy-of select="x:InternalNote" />
            <xsl:copy-of select="x:DummyProductLink" />
            <xsl:copy-of select="x:Status" />
            <xsl:copy-of select="x:State" />
            <xsl:copy-of select="x:UpdateNote" />
            <xsl:copy-of select="x:ThumbnailPath" />
            <xsl:copy-of select="x:SortOrder" />
            <xsl:copy-of select="x:EntryDate" />
            <xsl:copy-of select="x:ExpiryDate" />
            <xsl:copy-of select="x:SupersededDate" />
            <xsl:copy-of select="x:UpdateDate" />
            <xsl:copy-of select="x:WithdrawnDate" />
            <xsl:copy-of select="x:PluginName" />
            <xsl:copy-of select="x:S1" />
            <xsl:copy-of select="x:S2" />
            <xsl:copy-of select="x:S3" />
            <xsl:copy-of select="x:S4" />
            <xsl:copy-of select="x:S5" />
            <xsl:copy-of select="x:S6" />
            <xsl:copy-of select="x:S7" />
            <xsl:copy-of select="x:S8" />
            <xsl:copy-of select="x:S9" />
            <xsl:copy-of select="x:S10" />
            <xsl:copy-of select="x:HasLexConnect" />
            <xsl:copy-of select="x:HasCodeConnect" />
        </Product>
    </xsl:template>
    <xsl:template match="x:RelatedProduct">
        <xsl:copy>
            <xsl:apply-templates select="@*|*[not(name()='RelationId')]" />
            <RelationType>
                <xsl:value-of select="name(..)" />
            </RelationType>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

现在我需要将根元素重命名为 Products 而不是 Standards 并从输出中消除所有 nil 值。 nil 值具有以下格式。

 <Designation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
        <Abstract xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
        <History xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
        <TOC xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>

我添加了以下 xslt 段,将根元素重命名为 Products

<xsl:template match="x:Standards">
    <Products namespace="{namespace-uri()}">
        <xsl:apply-templates select=".//x:Standard" />
    </Products>
</xsl:template>

正确吗?如何更改上述 xslt 以消除输出中的所有 nil 值。任何帮助将不胜感激。

【问题讨论】:

  • “正确吗” -- 它是否产生了您期望的输出?您不必通过在此处提问来检查每项更改。试试吧!至于用xsi:nil="true"消除值,你知道如何为此编写一个匹配的模板,只需将模板设为空即可。
  • 我得到了预期的输出。但我还不能消除那个 nil 值。

标签: xml xslt xslt-1.0 xslt-2.0


【解决方案1】:

将 xsi 的命名空间声明添加到您的样式表中

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

添加模板忽略xsi:nil

<xsl:template match="@xsi:nil"/>

并将您的 xsl:copy-of 更改为 xsl:apply-templates。 例如更改:

<xsl:copy-of select="x:ProductID" />

到:

<xsl:apply-templates select="x:ProductID" />

更新:
要忽略所有具有 nil 属性的节点,请尝试:

<xsl:template match="*[@xsi:nil]"/>

【讨论】:

  • 我尝试了建议的方法,但现在我得到如下的空 xml 标签。 用于 nil 元素。要求是消除所有的零节点。
  • 是的 - 我以为这是你所期待的帽子。但听起来你喜欢忽略带有 nil 的元素,而不是 nil 属性
  • 非常感谢您的善意公司。这很有效。我的时间有点紧,没有足够的时间进行实验。再次感谢。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 2011-02-10
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
相关资源
最近更新 更多