2014-12-03 3 views
0

В преобразовании XSL есть две вещи, которые мне не удалось выяснить. В исходном XMLУдаление атрибутов и пустых элементов

<Network> 
    <Hosts> 
    <Host modelId="1" name="H1"> 
     <LinPorts> 
     <LinPort name="Port3" speed="100" parent="H1"/> 
     </LinPorts> 
     <CanPorts/> 
     <EthernetPorts> 
     <EthernetPort name="Port1" speed="100" parent="H1"/> 
     <EthernetPort name="Port2" speed="100" parent="H1"/> 
     </EthernetPorts> 
    </Host> 
    <Host modelId="1" name="H2"> 
     <CanPorts> 
     <CanPort name="Port2" speed="100" parent="H2"/> 
     </CanPorts> 
     <EthernetPorts> 
     <EthernetPort name="Port1" speed="100" parent="H3"/> 
     </EthernetPorts> 
    </Host> 
    <Host modelId="1" name="lin"> 
     <LinPorts> 
     <LinPort name="Port1" speed="10" parent="lin"/> 
     <LinPort name="Port2" speed="100" parent="H2"/> 
     <LinPort name="Port3" speed="100" parent="lin"/> 
     </LinPorts> 
    </Host> 
    </Hosts> 
    <DataFrames> 
    <DataFrame bitSize="21" name="greasd" offset="0.021" period="0.021" prio="0"> 
     <Path name="greasd-S5" parent="greasd"> 
     <Node name="H1" sequenceNumber="1" parent="greasd-S5"/> 
     <Node name="S5" sequenceNumber="2" parent="greasd-S5"/> 
     </Path> 
    </DataFrame> 
    <DataFrame bitSize="23" name="hytdsg" offset="0.423" period="0.423" prio="0"> 
     <Path name="hytdsg-H1" parent="hytdsg"> 
     <Node name="H2" sequenceNumber="1" parent="hytdsg-H1"/> 
     <Node name="S5" sequenceNumber="2" parent="hytdsg-H1"/> 
     <Node name="H1" sequenceNumber="3" parent="hytdsg-H1"/> 
     </Path> 
    </DataFrame> 
    </DataFrames> 
</Network> 

некоторые дочерние узлы были неправильно размещены. Я использую атрибут @parent, чтобы разместить их правильно. Это хорошо работает с использованием XSLT ниже.

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

<!-- Copy all nodes (that do not get a better match) as they are --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Host"> 
    <xsl:variable name="hostname" select="@name"/> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <LinPorts> 
      <xsl:apply-templates select="//LinPorts/LinPort[@parent=$hostname]"> 
       <xsl:sort select="@name" data-type="text" /> 
      </xsl:apply-templates> 
     </LinPorts> 
     <CanPorts> 
      <xsl:apply-templates select="//CanPorts/CanPort[@parent=$hostname]"> 
       <xsl:sort select="@name" data-type="text" /> 
      </xsl:apply-templates> 
     </CanPorts> 
     <EthernetPorts> 
      <xsl:apply-templates 
       select="//EthernetPorts/EthernetPort[@parent=$hostname]"> 
       <xsl:sort select="@name" data-type="text" /> 
      </xsl:apply-templates> 
     </EthernetPorts> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="DataFrame"> 
    <xsl:variable name="framename" select="@name"/> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="//Path[@parent=$framename]"> 
      <xsl:sort select="@name" data-type="text" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Path"> 
    <xsl:variable name="pathname" select="@name"/> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="//Node[@parent=$pathname]"> 
      <xsl:sort select="@sequenceNumber" data-type="text" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

<!-- Do not save attributes parent and ID for child elements --> 
<xsl:template match="CanPort|LinPort|EthernetPort|Node"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*[not(name()='parent') and not(name()='id')]"> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
  1. Я также создать элементы, которые являются пустыми (CanPorts, LinPorts, EthernetPorts). Как я могу избавиться от них?
  2. Я хочу избавиться от атрибута @parent. Мне удалось сделать это для всех элементов, кроме Path. Как избавиться от Path.parent?

ответ

1

Для точки 1, вы можете использовать xsl:if проверить счетчик LinPort, CanPort и EthernetPort перед созданием LinPorts, CanPorts и EthernetPorts элементы И для 2, добавьте еще один шаблон, соответствующий @parent и ничего не делает:

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

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

<xsl:template match="Host"> 
    <xsl:variable name="hostname" select="@name"/> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:if test="count(//LinPorts/LinPort[@parent=$hostname]) != 0"> 
      <LinPorts> 
       <xsl:apply-templates select="//LinPorts/LinPort[@parent=$hostname]"> 
        <xsl:sort select="@name" data-type="text" /> 
       </xsl:apply-templates> 
      </LinPorts> 
     </xsl:if> 
     <xsl:if test="count(//CanPorts/CanPort[@parent=$hostname]) != 0"> 
      <CanPorts> 
       <xsl:apply-templates select="//CanPorts/CanPort[@parent=$hostname]"> 
        <xsl:sort select="@name" data-type="text" /> 
       </xsl:apply-templates> 
      </CanPorts> 
     </xsl:if> 
     <xsl:if test="count(//EthernetPorts/EthernetPort[@parent=$hostname]) != 0"> 
      <EthernetPorts> 
       <xsl:apply-templates 
      select="//EthernetPorts/EthernetPort[@parent=$hostname]"> 
        <xsl:sort select="@name" data-type="text" /> 
       </xsl:apply-templates> 
      </EthernetPorts> 
     </xsl:if> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="DataFrame"> 
    <xsl:variable name="framename" select="@name"/> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="//Path[@parent=$framename]"> 
      <xsl:sort select="@name" data-type="text" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Path"> 
    <xsl:variable name="pathname" select="@name"/> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="//Node[@parent=$pathname]"> 
      <xsl:sort select="@sequenceNumber" data-type="text" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

<!-- Do not save attributes parent and ID for child elements --> 
<xsl:template match="CanPort|LinPort|EthernetPort|Node"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 
<!-- This template matches @parent and @id and does nothing --> 
<xsl:template match="@parent | @id"/> 
</xsl:stylesheet> 
Смежные вопросы