Как удалить определенные атрибуты из XML с помощью XLST - PullRequest
6 голосов
/ 30 мая 2011

Мне возвращается документ XML через веб-сервис.

<Kronos_WFC encoding="ASCII" version="1.0" WFCVersion="6.1" TimeStamp="01/5/2011 8:38AM">
  <Response Status="Success" Timeout="1800" PersonKey="-1" Object="System" Username="1" Action="Logon" PersonNumber="1">
  </Response>
  <Response Status="Success" action="Load">
      <ScheduleGroup ScheduleGroupName="SomeName" AllowsInheritance="false" AllowContract="false" IsEmploymentTerm="false" />
      <ScheduleGroup ScheduleGroupName="GreatName" AllowsInheritance="true" AllowContract="false" IsEmploymentTerm="false" />
      <ScheduleGroup ScheduleGroupName="BestName" AllowsInheritance="true" AllowContract="false" IsEmploymentTerm="false" />
  </Response>
  <Response Status="Success" Object="System" Action="Logoff">
  </Response>
</Kronos_WFC>

Проблема в том, что я превращаю результаты в бизнес-объекты, сгенерированные из схемы xsd для этого продукта (xsd2code). У продукта нет ничего в схеме для атрибутов (для Response):

  • Тайм-аут
  • PersonKey
  • Object
  • Имя пользователя

Я бы хотел сделать следующее:

  • Удалить вышеупомянутые атрибуты
  • Превратите все остальные атрибуты в элементы, включая всех детей, детей и т. Д.

Как мне сделать это с помощью XLST. Будет ли проще удалить ненужные атрибуты с помощью Regex?

1 Ответ

7 голосов
/ 30 мая 2011

Было бы проще удалить ненужные атрибуты с помощью Regex?

Нет, это очень простая операция XSLT:

Это преобразование :

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

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

 <xsl:template match=
 "Response/@*[contains('|Timeout|PersonKey|Object|Username|',
                      concat('|',name(),'|')
                      )
            ]"/>
 <xsl:template match="@*">
  <xsl:element name="{name()}">
   <xsl:value-of select="."/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<Kronos_WFC encoding="ASCII" version="1.0"
WFCVersion="6.1" TimeStamp="01/5/2011 8:38AM">
    <Response Status="Success" Timeout="1800" PersonKey="-1"
    Object="System" Username="1" Action="Logon"
    PersonNumber="1"></Response>
    <Response Status="Success" action="Load">
        <ScheduleGroup ScheduleGroupName="SomeName"
        AllowsInheritance="false" AllowContract="false"
        IsEmploymentTerm="false" />
        <ScheduleGroup ScheduleGroupName="GreatName"
        AllowsInheritance="true" AllowContract="false"
        IsEmploymentTerm="false" />
        <ScheduleGroup ScheduleGroupName="BestName"
        AllowsInheritance="true" AllowContract="false"
        IsEmploymentTerm="false" />
    </Response>
    <Response Status="Success" Object="System"
    Action="Logoff"></Response>
</Kronos_WFC>

дает именно нужный, правильный результат :

<Kronos_WFC>
   <encoding>ASCII</encoding>
   <version>1.0</version>
   <WFCVersion>6.1</WFCVersion>
   <TimeStamp>01/5/2011 8:38AM</TimeStamp>
   <Response>
      <Status>Success</Status>
      <Action>Logon</Action>
      <PersonNumber>1</PersonNumber>
   </Response>
   <Response>
      <Status>Success</Status>
      <action>Load</action>
      <ScheduleGroup>
         <ScheduleGroupName>SomeName</ScheduleGroupName>
         <AllowsInheritance>false</AllowsInheritance>
         <AllowContract>false</AllowContract>
         <IsEmploymentTerm>false</IsEmploymentTerm>
      </ScheduleGroup>
      <ScheduleGroup>
         <ScheduleGroupName>GreatName</ScheduleGroupName>
         <AllowsInheritance>true</AllowsInheritance>
         <AllowContract>false</AllowContract>
         <IsEmploymentTerm>false</IsEmploymentTerm>
      </ScheduleGroup>
      <ScheduleGroup>
         <ScheduleGroupName>BestName</ScheduleGroupName>
         <AllowsInheritance>true</AllowsInheritance>
         <AllowContract>false</AllowContract>
         <IsEmploymentTerm>false</IsEmploymentTerm>
      </ScheduleGroup>
   </Response>
   <Response>
      <Status>Success</Status>
      <Action>Logoff</Action>
   </Response>
</Kronos_WFC>

Объяснение:

  1. Правило / шаблон идентификации копирует каждый узел "как есть".

  2. Шаблон, переопределяющий правило идентификации, которое соответствует любому атрибуту с именем Timeout, PersonKey, Object или Username, имеет пустое тело и не копирует их («удаляет» их из выходных данных)

  3. Шаблон, соответствующий любому атрибуту, создает элемент, имя которого является именем сопоставленного атрибута, а текстовый узел-потомок является значением сопоставляемого атрибута.

Помните : использование и переопределение правило идентификации является самым фундаментальным и мощнымRful XSLT дизайн шаблон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...