简体   繁体   中英

Transforming a XML document into another XML schema

I want to transform an XML document with a specific schema into another XML document, giving it a specific different schema.

To give an example, the input could be as follows:

<?xml version="1.0" encoding="UTF-8"?>
<Abcd field1="0" field2="3" field3="1" field4="_sometext" field5="text" field6="Helloworld" />
<Efgh _id="2790" size="2">
    <i>2771</i>
    <i>2781</i>
</Efgh>

The corresponding output for this example is:

<?xml version="1.0" encoding="UTF-8"?>
<field name="Abcd"> field1="0" field2="3" field3="1" field4="_sometext" field5="text" field6="Helloworld" </field>
<field name="Efgh"> _id="2790" size="2"
    <i>2771</i>
    <i>2781</i>
</field>

There are only two types of tags:

  1. the ones like Abcd, with a variable number of fields (field1 to fieldN)
  2. the ones like Efgh, which also always have some number of < i >someText < / i > subtags. (The character 'i' is always the used there).

I am not sure how to attempt such a transformation (Regex? XSLT?).

If there would be only tags of form 1 (like Abcd), using sed in bash could do the work I think, but with tags of form 2, I do not know how to proceed.

Edit: I wrote a small pipeline using sed that transforms lines of form 1 into the correct counterpart, it works as follows:

cat input1.xml | sed "s/ * /\"> /" | sed "s/</<field name=\"/" | sed "s,/>,</field>,"

But how to continue?

I am going to take a guess here; given the following example input:

XML

<root>
    <Abcd field1="0" field2="3" field3="1" field4="_sometext" field5="text" field6="Helloworld" />
    <Efgh _id="2790" size="2">
        <i>2771</i>
        <i>2781</i>
    </Efgh>
</root>  

the following stylesheet:

XSLT 1.0

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

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

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

</xsl:stylesheet>

will result in:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <field name="Abcd" field1="0" field2="3" field3="1" field4="_sometext" field5="text" field6="Helloworld"/>
   <field name="Efgh" _id="2790" size="2">
      <i>2771</i>
      <i>2781</i>
   </field>
</root>

which to me seems much more likely to be the required output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM