XSLT-转换XML文件

XSLT-转换XML文件,xslt,Xslt,我想把xml文件格式转换成另一种格式; 使用XSL版本1.0或2.0 输入XML文件: <ROOT_XML> <Struct id="_6" name="Result" context="_1" members="_9 _10 _11 _13 _14 "/> <FundamentalType id="_7" name="int" size="32" align="32"/> <FundamentalType id="_8" name="flo

我想把xml文件格式转换成另一种格式; 使用XSL版本1.0或2.0

输入XML文件:

<ROOT_XML>
  <Struct id="_6" name="Result" context="_1" members="_9 _10 _11 _13 _14 "/>
  <FundamentalType id="_7" name="int" size="32" align="32"/>
  <FundamentalType id="_8" name="float" size="32" align="32"/>
  <Field id="_9" name="angle" type="_8" offset="0" context="_6"/>
  <Field id="_10" name="row" type="_7" offset="32" context="_6"/>
  <Field id="_11" name="cloth" type="_18" offset="96" context="_6"/>
  <Destructor id="_13" name="EmptyClass" artificial="1" throw="" context="_6">
  </Destructor>
  <Constructor id="_14" name="Result" context="_6">
    <Argument type="_20" location="f0:2" file="f0" line="2"/>
  </Constructor>
  <Constructor id="_15" name="Result" context="_6"/>
  <FundamentalType id="_17" name="unsigned int" size="32" align="32"/>
  <ArrayType id="_18" min="0" max="29u" type="_21" size="240" align="8"/>
  <ReferenceType id="_19" type="_6" size="32" align="32"/>
  <ReferenceType id="_20" type="_6c" size="32" align="32"/>
  <FundamentalType id="_21" name="char" size="8" align="8"/>
</ROOT_XML>
<Struct Result>
  <Fields>
    <Field name="angle"  type="float" size="32"/>
    <Field name="row"    type="int"   size="32"/>
    <Field name="cloth"  type="char"  size="240"/>
  </Fields> 
</Struct>

输出XML文件:

<ROOT_XML>
  <Struct id="_6" name="Result" context="_1" members="_9 _10 _11 _13 _14 "/>
  <FundamentalType id="_7" name="int" size="32" align="32"/>
  <FundamentalType id="_8" name="float" size="32" align="32"/>
  <Field id="_9" name="angle" type="_8" offset="0" context="_6"/>
  <Field id="_10" name="row" type="_7" offset="32" context="_6"/>
  <Field id="_11" name="cloth" type="_18" offset="96" context="_6"/>
  <Destructor id="_13" name="EmptyClass" artificial="1" throw="" context="_6">
  </Destructor>
  <Constructor id="_14" name="Result" context="_6">
    <Argument type="_20" location="f0:2" file="f0" line="2"/>
  </Constructor>
  <Constructor id="_15" name="Result" context="_6"/>
  <FundamentalType id="_17" name="unsigned int" size="32" align="32"/>
  <ArrayType id="_18" min="0" max="29u" type="_21" size="240" align="8"/>
  <ReferenceType id="_19" type="_6" size="32" align="32"/>
  <ReferenceType id="_20" type="_6c" size="32" align="32"/>
  <FundamentalType id="_21" name="char" size="8" align="8"/>
</ROOT_XML>
<Struct Result>
  <Fields>
    <Field name="angle"  type="float" size="32"/>
    <Field name="row"    type="int"   size="32"/>
    <Field name="cloth"  type="char"  size="240"/>
  </Fields> 
</Struct>


下面是一个关于如何解析“members”属性列表的示例

http://www.w3.org/1999/XSL/Transform“version=“1.0”>


此代码是从“Struct”节点的“members”属性中提取相关id的起点,以后仅用于发出“Field”节点

此外,输出XML文件可能包含多个“Struct”节点, 例如:




谢谢你的回复。不过,我还是想强调一下如何获得xml输出的逻辑

xslt处理器需要解析结构节点的“members”属性。 “members”属性是字段ID的列表

在上述示例中:

只有“members=\u9\u10\u11”是字段节点!因此它们应该像Michael之前所做的那样输出。 列表中的其余项目被省略(即成员=“\u 13\u 14”)

组合代码:(我需要帮助才能继续…) http://www.w3.org/1999/XSL/Transform“version=“1.0”>



以下样式表:

XSLT1.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="*"/>

<xsl:key name="f-type" match="FundamentalType" use="@id" />
<xsl:key name="a-type" match="ArrayType" use="@id" />

<xsl:template match="ROOT_XML">
    <Struct>
        <xsl:apply-templates select="Field"/>
    </Struct>
</xsl:template> 

<xsl:template match="Field[key('f-type', @type)]">
    <xsl:variable name="f-type" select="key('f-type', @type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$f-type/@size}"/>   
</xsl:template>

<xsl:template match="Field[key('a-type', @type)]">
    <xsl:variable name="a-type" select="key('a-type', @type)" />
    <xsl:variable name="f-type" select="key('f-type', $a-type/@type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$a-type/@size}"/>   
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="2.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="*"/>

<xsl:key name="field" match="Field" use="@id" />
<xsl:key name="f-type" match="FundamentalType" use="@id" />
<xsl:key name="a-type" match="ArrayType" use="@id" />

<xsl:variable name="xml" select="/" />

<xsl:template match="/ROOT_XML">
    <root>
        <xsl:for-each select="Struct">
            <Struct name="{@name}">
                <xsl:apply-templates select="key('field', tokenize(@members, ' '))"/>
            </Struct>
        </xsl:for-each> 
    </root>
</xsl:template> 

<xsl:template match="Field[key('f-type', @type)]">
    <xsl:variable name="f-type" select="key('f-type', @type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$f-type/@size}"/>   
</xsl:template>

<xsl:template match="Field[key('a-type', @type)]">
    <xsl:variable name="a-type" select="key('a-type', @type)" />
    <xsl:variable name="f-type" select="key('f-type', $a-type/@type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$a-type/@size}"/>   
</xsl:template>

</xsl:stylesheet>

编辑2 XSLT 1.0中的相同内容:

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

<xsl:key name="field" match="Field" use="@id" />
<xsl:key name="f-type" match="FundamentalType" use="@id" />
<xsl:key name="a-type" match="ArrayType" use="@id" />

<xsl:variable name="xml" select="/" />

<xsl:template match="/ROOT_XML">
    <root>
        <xsl:for-each select="Struct">
            <xsl:variable name="members">
                <xsl:call-template name="tokenize">
                    <xsl:with-param name="text" select="@members"/>
                </xsl:call-template>
            </xsl:variable>
            <Struct name="{@name}">
                <xsl:apply-templates select="key('field', exsl:node-set($members)/token)"/>
            </Struct>
        </xsl:for-each> 
    </root>
</xsl:template> 

<xsl:template match="Field[key('f-type', @type)]">
    <xsl:variable name="f-type" select="key('f-type', @type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$f-type/@size}"/>   
</xsl:template>

<xsl:template match="Field[key('a-type', @type)]">
    <xsl:variable name="a-type" select="key('a-type', @type)" />
    <xsl:variable name="f-type" select="key('f-type', $a-type/@type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$a-type/@size}"/>   
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="' '"/>
    <xsl:choose>
        <xsl:when test="contains($text, $delimiter)">
            <token>
                <xsl:value-of select="substring-before($text, $delimiter)"/>
            </token>
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <token>
                <xsl:value-of select="$text"/>
            </token>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>


</xsl:stylesheet>

以下样式表:

XSLT1.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="*"/>

<xsl:key name="f-type" match="FundamentalType" use="@id" />
<xsl:key name="a-type" match="ArrayType" use="@id" />

<xsl:template match="ROOT_XML">
    <Struct>
        <xsl:apply-templates select="Field"/>
    </Struct>
</xsl:template> 

<xsl:template match="Field[key('f-type', @type)]">
    <xsl:variable name="f-type" select="key('f-type', @type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$f-type/@size}"/>   
</xsl:template>

<xsl:template match="Field[key('a-type', @type)]">
    <xsl:variable name="a-type" select="key('a-type', @type)" />
    <xsl:variable name="f-type" select="key('f-type', $a-type/@type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$a-type/@size}"/>   
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="2.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="*"/>

<xsl:key name="field" match="Field" use="@id" />
<xsl:key name="f-type" match="FundamentalType" use="@id" />
<xsl:key name="a-type" match="ArrayType" use="@id" />

<xsl:variable name="xml" select="/" />

<xsl:template match="/ROOT_XML">
    <root>
        <xsl:for-each select="Struct">
            <Struct name="{@name}">
                <xsl:apply-templates select="key('field', tokenize(@members, ' '))"/>
            </Struct>
        </xsl:for-each> 
    </root>
</xsl:template> 

<xsl:template match="Field[key('f-type', @type)]">
    <xsl:variable name="f-type" select="key('f-type', @type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$f-type/@size}"/>   
</xsl:template>

<xsl:template match="Field[key('a-type', @type)]">
    <xsl:variable name="a-type" select="key('a-type', @type)" />
    <xsl:variable name="f-type" select="key('f-type', $a-type/@type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$a-type/@size}"/>   
</xsl:template>

</xsl:stylesheet>

编辑2 XSLT 1.0中的相同内容:

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

<xsl:key name="field" match="Field" use="@id" />
<xsl:key name="f-type" match="FundamentalType" use="@id" />
<xsl:key name="a-type" match="ArrayType" use="@id" />

<xsl:variable name="xml" select="/" />

<xsl:template match="/ROOT_XML">
    <root>
        <xsl:for-each select="Struct">
            <xsl:variable name="members">
                <xsl:call-template name="tokenize">
                    <xsl:with-param name="text" select="@members"/>
                </xsl:call-template>
            </xsl:variable>
            <Struct name="{@name}">
                <xsl:apply-templates select="key('field', exsl:node-set($members)/token)"/>
            </Struct>
        </xsl:for-each> 
    </root>
</xsl:template> 

<xsl:template match="Field[key('f-type', @type)]">
    <xsl:variable name="f-type" select="key('f-type', @type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$f-type/@size}"/>   
</xsl:template>

<xsl:template match="Field[key('a-type', @type)]">
    <xsl:variable name="a-type" select="key('a-type', @type)" />
    <xsl:variable name="f-type" select="key('f-type', $a-type/@type)" />
    <Field name="{@name}" type="{$f-type/@name}" size="{$a-type/@size}"/>   
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="' '"/>
    <xsl:choose>
        <xsl:when test="contains($text, $delimiter)">
            <token>
                <xsl:value-of select="substring-before($text, $delimiter)"/>
            </token>
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <token>
                <xsl:value-of select="$text"/>
            </token>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>


</xsl:stylesheet>


欢迎使用堆栈溢出!堆栈溢出不是一种代码编写服务,您需要显示到目前为止您得到了什么,以及在哪里遇到了问题。请阅读。作为一个新用户,您可能也应该阅读介绍<代码>是糟糕的XML,顺便说一下。可以通过XSLT创建该属性,但不能将
output
设置为
XML
。此外,您很难告诉渲染器在属性之间输出多个空格。您能解释一下这里需要应用的逻辑吗?一个或两个示例没有建立规则。@Dan您的“答案”已移至您的问题-正如其他人所提到的-答案应用于答案-如果您想澄清/添加其他信息,而不是通过取消您的问题。谢谢。欢迎来到Stack Overflow!堆栈溢出不是一种代码编写服务,您需要显示到目前为止您得到了什么,以及在哪里遇到了问题。请阅读。作为一个新用户,您可能也应该阅读介绍<代码>是糟糕的XML,顺便说一下。可以通过XSLT创建该属性,但不能将
output
设置为
XML
。此外,您很难告诉渲染器在属性之间输出多个空格。您能解释一下这里需要应用的逻辑吗?一个或两个示例没有建立规则。@Dan您的“答案”已移至您的问题-正如其他人所提到的-答案应用于答案-如果您想澄清/添加其他信息,而不是通过取消您的问题。谢谢,太好了。您的答案使用XSLT2.0是有效的。评论:1。.Net是否支持XSLT2.0?如果没有,是否可以使用XSLT1.0重写答案?2.对XML输出进行微调:1。如果您的处理器不支持XSLT2.0,则不应该要求使用XSLT2.0解决方案。Microsoft处理器仅支持XSLT 1.0。如果要在.NET中使用XSLT2.0,必须安装第三方XSLT处理器。我在回答中添加了XSLT1.0解决方案。-2.查看编辑后的答案。感谢您的帮助。使用Oxgen和.NET.Hi,效果很好。您的答案使用XSLT2.0是有效的。评论:1。.Net是否支持XSLT2.0?如果没有,是否可以使用XSLT1.0重写答案?2.对XML输出进行微调:1。您不应该要求使用XSLT2.0