Transform XML to add 'nil' attributes to e

2019-08-29 21:45发布

An existing XML feed we consume has a lot of properties whose values can be missing, and we want to treat these as NULL not optional or empty values because it makes enforcing strict typing harder and messes up our auto code generation and so on.

For instance we might receive: <LASTUPDATED/>

We have no formal XSD but are creating one ourselves... it might currently look like: <xs:element type="xs:dateTime" name="LASTUPDATED"/>

This doesn't validate against the XML shown ("" is not a valid dateTime). Ideally it would instead have xsi:nil=true in the XML (nillable and minOccurs XSD element attributes)

Since we don't control the feed, can I create a transform that will replace any <xxx/> element with <myElement xsi:nil='true'/>? Instead changing our XSD to use minOccurs is not great because then we have to check if each element exists or not rather than just supporting NULL values.

标签: xml xslt xsd
1条回答
干净又极端
2楼-- · 2019-08-29 22:06

The following should work.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="*[not(text())]">
        <xsl:copy>
            <xsl:attribute name="xsi:nil">true</xsl:attribute>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

This however, will also match <LASTUPDATED></LASTUPDATED> which is semantically identical to <LASTUPDATED />

查看更多
登录 后发表回答