XSLT: Reduce XML to fit Schema

Discussion in 'XML' started by C. Marco, Aug 14, 2009.

  1. C. Marco

    C. Marco Guest

    Hi all,

    I posted this in XSLT group before but maybe you can help me in here,
    too. So sorry to everyone who got this question twice because you're
    in both groups.

    Anyway, I'm pretty unexperienced using XSLT and I have a little
    question which I hope can be answered here:
    Is there a simple way to reduce an existing XML file to make it fit a
    XML Schema?

    For example if I have a XML file like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://test/"
    xsi:schemaLocation="http://test/ result.xsd">
    <b>Node B</b>
    <c>Node C</c>
    <m>
    <x>Node X1</x>
    <y>Node Y1</y>
    <z>Node Z1</z>
    <m>
    <x>Node X2</x>
    <y>Node Y2</y>
    <z>Node Z2</z>
    </m>
    </m>
    </a>

    and I want to create a copy of this file only with the correct nodes
    so that it fits a XSD like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://test/"
    targetNamespace="http://test/"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified">
    <xs:element name="a">
    <xs:complexType>
    <xs:sequence>
    <xs:element ref="tns:b"/>
    <xs:element ref="tns:m"/>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    <xs:element name="m">
    <xs:complexType>
    <xs:sequence>
    <xs:element ref="tns:x" minOccurs="0"/>
    <xs:element ref="tns:y"/>
    <xs:element ref="tns:m" minOccurs="0"/>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    <xs:element name="b">
    <xs:simpleType>
    <xs:restriction base="xs:string"/>
    </xs:simpleType>
    </xs:element>
    <xs:element name="x">
    <xs:simpleType>
    <xs:restriction base="xs:string"/>
    </xs:simpleType>
    </xs:element>
    <xs:element name="y">
    <xs:simpleType>
    <xs:restriction base="xs:string"/>
    </xs:simpleType>
    </xs:element>
    </xs:schema>

    I'm sure this can be done with XSLT and I guess it surely doesn't take
    much effort to do this. Can anyone give me a little hint on how to
    solve this? Thank you!

    Best regards,
    Chris Marco
     
    C. Marco, Aug 14, 2009
    #1
    1. Advertising

  2. There isn't a really good way to automate the process of discarding
    things that don't fit the schema. Even XSLT 2.0, which has some schema
    awareness, is mostly concerned with checking for validity and
    manipulating schema-typed data rather than adjusting an invalid document
    to make it valid.

    But it certainly shouldn't be difficult to hand-construct a stylesheet
    which maps your source document structure into one that fits the desired
    schema.
     
    Joe Kesselman, Aug 14, 2009
    #2
    1. Advertising

  3. C. Marco wrote:

    > I'm sure this can be done with XSLT and I guess it surely doesn't take
    > much effort to do this. Can anyone give me a little hint on how to
    > solve this? Thank you!


    Do you expect the author of the XSLT stylesheet to read the schema and
    author an appropriate XSLT stylesheet? Someone skilled with schemas and
    stylesheet can certainly do that.
    Or do you expect the XSLT stylesheet to be generic and pull in the
    schema and then based on the schema to generate the output? That is far
    from being trivial, with the complexity the W3C XML schema language has.

    Here is my attempt to write a stylesheet based on the XML input and the
    schema you have provided, it simply copies everything recursively
    besides the 'c' and 'z' elements:

    <xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:test="http://test/"
    version="1.0">

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

    <xsl:template match="test:c | test:z"/>

    </xsl:stylesheet>

    That way you get

    <?xml version="1.0" encoding="UTF-8"?>
    <a xmlns="http://test/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://test/ test2009081401Xsd.xml">
    <b>Node B</b>

    <m>
    <x>Node X1</x>
    <y>Node Y1</y>

    <m>
    <x>Node X2</x>
    <y>Node Y2</y>

    </m>
    </m>
    </a>


    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
     
    Martin Honnen, Aug 14, 2009
    #3
  4. C. Marco

    C. Marco Guest

    On 14 Aug., 16:27, Martin Honnen <> wrote:
    > That way you get


    Perfect, that absolutely fits my needs. Of course the files I'm
    working with are a little larger but I guess I can map your solution
    to my scenario. Thanks a lot!
     
    C. Marco, Aug 17, 2009
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page