使用 xslt 更改 xml 的输出

Changing the output of xml using xslt

如何更改 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 还很陌生,所以我在编写代码时可能会犯一些错误

你的模板有两个原因:

<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>