Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用xslt对xml文件元素排序_Xml_Xslt - Fatal编程技术网

使用xslt对xml文件元素排序

使用xslt对xml文件元素排序,xml,xslt,Xml,Xslt,我有以下xml文件: <WindowProperties> <skin>LP Connect</skin> <showToOperator>false</showToOperator> <showToVisitor>false</showToVisitor> <ChatWindow> <field> <key>direction</key> &l

我有以下xml文件:

<WindowProperties>
<skin>LP Connect</skin>
<showToOperator>false</showToOperator>
<showToVisitor>false</showToVisitor>
<ChatWindow>
  <field>
    <key>direction</key>
    <val>ltr</val>
  </field>
  <field>
    <key>enableCustomizedHeaderImageUrl</key>
    <val>false</val>
  </field>
  <field>
    <key>brandType</key>
    <val>noImage</val>
  </field>
  <field>
    <key>brandHeight</key>
    <val>158</val>
  </field>      
</ChatWindow>

低压连接
假的
假的
方向
ltr
启用CustomizedHeaderImage URL
假的
品牌类型
无图像
品牌高度
158

我想使用key元素对聊天窗口中的字段进行排序,使xml看起来像:

<WindowProperties>
    <skin>LP Connect</skin>
    <showToOperator>false</showToOperator>
    <showToVisitor>false</showToVisitor>
    <ChatWindow>
    <field>
        <key>brandHeight</key>
        <val>158</val>
      </field> 
<field>
        <key>brandType</key>
        <val>noImage</val>
      </field>

      <field>
        <key>direction</key>
        <val>ltr</val>
      </field>
      <field>
        <key>enableCustomizedHeaderImageUrl</key>
        <val>false</val>
      </field>

    </ChatWindow>
 </WindowProperties>

低压连接
假的
假的
品牌高度
158
品牌类型
无图像
方向
ltr
启用CustomizedHeaderImage URL
假的
我尝试了以下xsl:

<ChatWindow>

                    <xsl:template match="ChatWindow">
                        <xsl:for-each select="field">
                            <xsl:sort select="key"/>
                            <key><xsl:value-of select="key"/></key>
                            <value><xsl:value-of select="val"/></value>
                        </xsl:for-each>
                    </xsl:template>

                </ChatWindow>


但这不起作用。感谢您的帮助。

编辑:请参阅@JLRishe的答案,因为这是正确的做法。我下面的答案满足“文本”输出要求,但实际上更复杂,可以完成相同的任务

我已经删除了完整的示例,并保留了原始答案中的
代码,我将保留在这里,以防任何人需要在XSLT的文本输出中生成XML元素或其他标记(例如用于生成注释或其他内容)。如果您希望生成纯XML,这不是最好的方法:

原始答案:

为了让我理解这个问题,您有一个返回“文本”(而不是XML)的XSLT模板,但是您希望在输出中保留XML标记,使其看起来像XML

为此,您需要围绕要作为文本处理的XML标记的
部分,如下所示:

    <xsl:template match="ChatWindow">
      <xsl:for-each select="field">
        <xsl:sort select="key"/>
        <![CDATA[<key>]]>
          <xsl:value-of select="key"/>
        <![CDATA[</key>]]>
        <![CDATA[<value>]]> 
          <xsl:value-of select="val"/>
        <![CDATA[</value>]]>
      </xsl:for-each>
    </xsl:template>

]]>
]]>
]]> 
]]>
注意,你也可以在中间做这一点来组合CDATA部分,但是我认为上面看起来更干净。(相同结果)


]]>
]]>
]]>

编辑:请查看@JLRishe的答案,因为这是正确的方法。我下面的答案满足“文本”输出要求,但实际上更复杂,可以完成相同的任务

我已经删除了完整的示例,并保留了原始答案中的
代码,我将保留在这里,以防任何人需要在XSLT的文本输出中生成XML元素或其他标记(例如用于生成注释或其他内容)。如果您希望生成纯XML,这不是最好的方法:

原始答案:

为了让我理解这个问题,您有一个返回“文本”(而不是XML)的XSLT模板,但是您希望在输出中保留XML标记,使其看起来像XML

为此,您需要围绕要作为文本处理的XML标记的
部分,如下所示:

    <xsl:template match="ChatWindow">
      <xsl:for-each select="field">
        <xsl:sort select="key"/>
        <![CDATA[<key>]]>
          <xsl:value-of select="key"/>
        <![CDATA[</key>]]>
        <![CDATA[<value>]]> 
          <xsl:value-of select="val"/>
        <![CDATA[</value>]]>
      </xsl:for-each>
    </xsl:template>

]]>
]]>
]]> 
]]>
注意,你也可以在中间做这一点来组合CDATA部分,但是我认为上面看起来更干净。(相同结果)


]]>
]]>
]]>

这个简单的XSLT应该可以完成以下工作:

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

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

  <xsl:template match="ChatWindow">
    <xsl:copy>
      <xsl:apply-templates select="field">
        <xsl:sort select="key" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

在样例输入上运行时,将生成:

<WindowProperties>
  <skin>LP Connect</skin>
  <showToOperator>false</showToOperator>
  <showToVisitor>false</showToVisitor>
  <ChatWindow>
    <field>
      <key>brandHeight</key>
      <val>158</val>
    </field>
    <field>
      <key>brandType</key>
      <val>noImage</val>
    </field>
    <field>
      <key>direction</key>
      <val>ltr</val>
    </field>
    <field>
      <key>enableCustomizedHeaderImageUrl</key>
      <val>false</val>
    </field>
  </ChatWindow>
</WindowProperties>

低压连接
假的
假的
品牌高度
158
品牌类型
无图像
方向
ltr
启用CustomizedHeaderImage URL
假的
如果出于某种原因您必须使用
,您可以执行以下操作,但我不建议您这样做:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="*">
    <xsl:value-of select="concat('&lt;', name(), '&gt;')"/>
    <xsl:apply-templates />
    <xsl:value-of select="concat('&lt;/', name(), '&gt;')"/>
  </xsl:template>

  <xsl:template match="ChatWindow">
    <xsl:value-of select="concat('&lt;', name(), '&gt;')"/>
    <xsl:apply-templates select="field">
      <xsl:sort select="key" />
    </xsl:apply-templates>
    <xsl:value-of select="concat('&lt;/', name(), '&gt;')"/>
  </xsl:template>
</xsl:stylesheet>

或者更长一点,但更干净一点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes" omit-xml-declaration="yes" />

  <xsl:template name="tag">
    <xsl:param name="slash" />
    <xsl:value-of select="concat('&lt;', $slash, name(), '&gt;')"/>
  </xsl:template>

  <xsl:template name="cTag">
    <xsl:call-template name="tag">
      <xsl:with-param name="slash" select="'/'" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="*">
    <xsl:call-template name="tag" />
    <xsl:apply-templates />
    <xsl:call-template name="cTag" />
  </xsl:template>

  <xsl:template match="ChatWindow">
    <xsl:call-template name="tag" />
    <xsl:apply-templates select="field">
      <xsl:sort select="key" />
    </xsl:apply-templates>
    <xsl:call-template name="cTag" />
  </xsl:template>
</xsl:stylesheet>

这个简单的XSLT应该可以完成以下工作:

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

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

  <xsl:template match="ChatWindow">
    <xsl:copy>
      <xsl:apply-templates select="field">
        <xsl:sort select="key" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

在样例输入上运行时,将生成:

<WindowProperties>
  <skin>LP Connect</skin>
  <showToOperator>false</showToOperator>
  <showToVisitor>false</showToVisitor>
  <ChatWindow>
    <field>
      <key>brandHeight</key>
      <val>158</val>
    </field>
    <field>
      <key>brandType</key>
      <val>noImage</val>
    </field>
    <field>
      <key>direction</key>
      <val>ltr</val>
    </field>
    <field>
      <key>enableCustomizedHeaderImageUrl</key>
      <val>false</val>
    </field>
  </ChatWindow>
</WindowProperties>

低压连接
假的
假的
品牌高度
158
品牌类型
无图像
方向
ltr
启用CustomizedHeaderImage URL
假的
如果出于某种原因您必须使用
,您可以执行以下操作,但我不建议您这样做:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="*">
    <xsl:value-of select="concat('&lt;', name(), '&gt;')"/>
    <xsl:apply-templates />
    <xsl:value-of select="concat('&lt;/', name(), '&gt;')"/>
  </xsl:template>

  <xsl:template match="ChatWindow">
    <xsl:value-of select="concat('&lt;', name(), '&gt;')"/>
    <xsl:apply-templates select="field">
      <xsl:sort select="key" />
    </xsl:apply-templates>
    <xsl:value-of select="concat('&lt;/', name(), '&gt;')"/>
  </xsl:template>
</xsl:stylesheet>

或者更长一点,但更干净一点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes" omit-xml-declaration="yes" />

  <xsl:template name="tag">
    <xsl:param name="slash" />
    <xsl:value-of select="concat('&lt;', $slash, name(), '&gt;')"/>
  </xsl:template>

  <xsl:template name="cTag">
    <xsl:call-template name="tag">
      <xsl:with-param name="slash" select="'/'" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="*">
    <xsl:call-template name="tag" />
    <xsl:apply-templates />
    <xsl:call-template name="cTag" />
  </xsl:template>

  <xsl:template match="ChatWindow">
    <xsl:call-template name="tag" />
    <xsl:apply-templates select="field">
      <xsl:sort select="key" />
    </xsl:apply-templates>
    <xsl:call-template name="cTag" />
  </xsl:template>
</xsl:stylesheet>


这个问题的公认答案应该对您有所帮助—它返回纯文本而不是XML—XSLT的输出应该是无关的—您正在对输入进行排序,然后对其执行所需操作。这个问题的答案的要点是,您需要在字段/键上进行匹配,而不是仅仅在键上进行匹配,我想您可以将其作为xsl编写,因为我对xslt一无所知?您所说的“这返回的是纯文本而不是xml”是什么意思?显然,您希望生成XML。这个问题的公认答案应该对您有所帮助—它返回纯文本而不是XML—XSLT的输出应该是无关的—您正在对输入进行排序,然后对其执行所需操作。这个问题的答案的要点是,您需要在字段/键上进行匹配,而不是仅仅在键上进行匹配,我想您可以将其作为xsl编写,因为我对xslt一无所知?您所说的“这返回的是纯文本而不是xml”是什么意思?显然,您希望生成XML。您可以编写完整的xsl文件来生成所有XML元素吗?谢谢David的帮助help@David如果您感兴趣,我已经添加了两个简洁而完整的解决方案