Изменение вывода xml с помощью xslt - PullRequest
0 голосов
/ 21 октября 2019

Как изменить вывод 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>.

Это код xslt, которыйЯ использовал для изменения формата XML

<?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, поэтому я мог иметь определенные ошибки при написании кода

1 Ответ

0 голосов
/ 23 октября 2019

Существует две причины, по которым ваш шаблон:

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