Вопрос

Can you tell me how to peform this using XSLT ?

Input:

<?xml version="1.0"?>
<A>
  <BB bb1="bb1" />
  <CC cc1="cc1" />
  <DD name="name1">
    <EEE type="foo" value="50">
      <FFFF id="id1">
    </EEE>
  </DD>
  <DD name="name2">
    <EEE type="bar" value="50">
      <FFFF id="id2">
    </EEE>
  </DD>
  <DD name="name3">
    <EEE type="foo" value="40">
      <FFFF id="id3">
    </EEE>
  </DD>

Output:

<?xml version="1.0"?>
<A>
  <BB bb1="bb1" />
  <CC cc1="cc1" />
  <DD name="name3">
    <EEE type="foo" value="40">
      <FFFF id="id3">
    </EEE>
  </DD>
  <DD name="name1">
    <EEE type="foo" value="50">
      <FFFF id="id1">
    </EEE>
  </DD>

I.e. copy all except that if it is a DD, copy only if EEE/@type = "foo", and sort all DD by EEE/@value.

For now i've just found xsl code to copy everything and sort by say EEE/@type for example.

XSLT:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()">
        <xsl:sort select="EEE/@type" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

That's already good enough but I really want to keep only those DD where EEE/@type = foo.

Thank You very much.

Это было полезно?

Решение

To

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()">
        <xsl:sort select="EEE/@type" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

you just need to add a template

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()">
        <xsl:sort select="EEE/@type" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="DD[not(EEE/@type = 'foo')]"/>

that ensures those DD elements with EEE/@type not equal 'foo' are not copied.

Другие советы

Just try to select the nodes you want with xpath

This should only copy 'EEE' elements with attribute type=foo

<xsl:template match="//EEE[@type='foo']">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top