首页 > 解决方案 > 使用 xslt 更改 xml 的输出

问题描述

如何更改xml的输出。

这是我得到的输出。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message">

<Header> </Header>
  <Body>
    <MessageParts xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message">
      <Run xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Run">

        <RunObject class="entity">
          <A1>NA</A1>
          <A2>False</A2>
          <A3>02</A3>
          <A4>ER</A4>
        </RunObject>

        <RunObject class="entity">
          <A1>NA</A1>
          <A2>False</A2>
          <A3>03</A3>
          <A4>ER</A4>
        </RunObject>

      </Run>
    </MessageParts>
  </Body>
</Envelope>

我想要的输出是这个

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>

  <Header> </Header>
  <Body>
    <Document>

      <Item>
        <A1>NA</A1>
        <A2>False</A2>
        <A3>02</A3>
        <A4>ER</A4>
      </Item>

      <Item>
        <A1>NA</A1>
        <A2>False</A2>
        <A3>03</A3>
        <A4>ER</A4>
      </Item>

    </Document>
  </Body>
</Envelope>

我已经尝试了各种各样的事情,但我仍然不会做出最后的改变。

我无法更改<Runobject class="Entity"><Item>.

这是我用来更改 xml 格式的 xslt 代码

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:s="http://schemas.microsoft.com/dynamics/2008/01/documents/Run"
>
  <xsl:output method="xml" indent="yes"/>

**Removes the run tag along with the namespace
  <xsl:template match="s:Run">
    <xsl:apply-templates select="*"/>
  </xsl:template>

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

**Used this code to replace the <RunObject class="entity"> with <Item> but is not working
  <xsl:template match="RunObject[@class='Entity']">
    <xsl:element name="Item">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>


  **Removes all namespaces
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>



  **Copies attributes
  <xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>

    </xsl:attribute>
  </xsl:template>





  <!-- template to copy the rest of the nodes -->
  <xsl:template match="comment() | text() | processing-instruction()">
    <xsl:copy/>
  </xsl:template>


</xsl:stylesheet>

我对 xslt 还很陌生,所以我在编写代码时可能会遇到某些错误

标签: xslt-1.0

解决方案


您的模板有两个原因:

<xsl:template match="RunObject[@class='Entity']">
    <xsl:element name="Item">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>

不匹配任何东西:

  1. RunObject在命名空间中,并且您没有使用前缀;
  2. XML 区分大小写;该class属性包含"entity",不"Entity"

如果您这样做,它应该可以工作:

<xsl:template match="s:RunObject[@class='entity']">
    <xsl:element name="Item">
      <xsl:apply-templates />
    </xsl:element>
</xsl:template>

除此之外,我相信你可以大大缩短整个事情 - 说:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:m="http://schemas.microsoft.com/dynamics/2011/01/documents/Message"
xmlns:r="http://schemas.microsoft.com/dynamics/2008/01/documents/Run"
exclude-result-prefixes="m r">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- move all elements to no namespace -->
<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

<!-- rename MessageParts to Document + skip the Run wrapper -->
<xsl:template match="m:MessageParts">
    <Document>
        <xsl:apply-templates select="r:Run/*"/>
    </Document>
</xsl:template>

<!-- rename RunObject to Item -->
<xsl:template match="r:RunObject[@class='entity']">
    <Item>
        <xsl:apply-templates />
    </Item>
</xsl:template>

</xsl:stylesheet>

推荐阅读