开发者

Removing an element who's child element value is 0 through XSLT

I have an xml file which I need to transform with XSLT. In my XSLT file I'm doing a number of things with the xml file. I first copy all elements; then I rename some of the elements. Lastly I need to remove for output any dealer-code element that has a dealer-code-name of 0. The 1st 2 pieces I have working, but I've tried every piece of code I've found online and can't seem to remove those offending dealer-code elements. I'm new to XSLT so I may be doing it all wrong; any help would be appreciated.

Partial xml code:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <?xml-stylesheet type="text/xsl" href="xmlstructure.xsl"?>
 <AdBaseData>
  <AdBasePreprintInfo FromDistribute="true">
       <PreprintInsert>
        <Sides>2</Sides>
        <PageCount>2</PageCount>
        <InsertSchedule>
            <AdLocInfo>
                <rundates>
                    <date>12042010</date>
                </rundates>
            </AdLocInfo>
            <invoice-text>South Plaza - Stalker Advertisin</invoice-text>
            <BillingOverride Type="Subscriber">49996</BillingOverride>
            <deal-code0>
                <dealer-code-name>A20</dealer-code-name>
                <Delivery-Method Type="Subscriber">
                    <Selected>true</Selected>
                </Delivery-Method>
            </deal-code0>
            <deal-code1>
                <dealer-code-name>0</dealer-code-name>
                <Delivery-Method Type="Subscriber">
                    <Selected>true</Selected>
                </Delivery-Method>
            </deal-code1>
  </InsertSchedule>
</PreprintInsert>

My xslt:

   <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3开发者_如何学C.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
     <xsl:template match="@* | node()">
       <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
       </xsl:copy>
     </xsl:template>
    <xsl:template match="*[starts-with(name(), 'deal-code')]">
       <xsl:element name="dealer-code">
         <xsl:apply-templates/>
       </xsl:element>
     </xsl:template>
     <xsl:template match="dealer-code[@dealer-code-name='0']">
     </xsl:template>
    </xsl:stylesheet>

The rename of deal-code to dealer-code works. However, the last part to not output any dealer-code-name with a value of 0 does not. My resulting xml file still lists every dealer-code element.


This input:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="xmlstructure.xsl"?>
<AdBaseData>
  <AdBasePreprintInfo FromDistribute="true">
    <PreprintInsert>
      <Sides>2</Sides>
      <PageCount>2</PageCount>
      <InsertSchedule>
        <AdLocInfo>
          <rundates>
            <date>12042010</date>
          </rundates>
        </AdLocInfo>
        <invoice-text>South Plaza - Stalker Advertisin</invoice-text>
        <BillingOverride Type="Subscriber">49996</BillingOverride>
        <deal-code0>
          <dealer-code-name>A20</dealer-code-name>
          <Delivery-Method Type="Subscriber">
            <Selected>true</Selected>
          </Delivery-Method>
        </deal-code0>
        <deal-code1>
          <dealer-code-name>0</dealer-code-name>
          <Delivery-Method Type="Subscriber">
            <Selected>true</Selected>
          </Delivery-Method>
        </deal-code1>
      </InsertSchedule>
    </PreprintInsert>
  </AdBasePreprintInfo>
</AdBaseData>

with this stylesheet:

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

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

  <xsl:template match="*[starts-with(name(), 'deal-code')][dealer-code-name = '0']"/>

</xsl:stylesheet>

produces the output you're wanting:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xmlstructure.xsl"?><AdBaseData>
   <AdBasePreprintInfo FromDistribute="true">
      <PreprintInsert>
         <Sides>2</Sides>
         <PageCount>2</PageCount>
         <InsertSchedule>
            <AdLocInfo>
               <rundates>
                  <date>12042010</date>
               </rundates>
            </AdLocInfo>
            <invoice-text>South Plaza - Stalker Advertisin</invoice-text>
            <BillingOverride Type="Subscriber">49996</BillingOverride>
            <deal-code0>
               <dealer-code-name>A20</dealer-code-name>
               <Delivery-Method Type="Subscriber">
                  <Selected>true</Selected>
               </Delivery-Method>
            </deal-code0>
         </InsertSchedule>
      </PreprintInsert>
   </AdBasePreprintInfo>
</AdBaseData>


You have two problems:

  1. You do not have any dealer-code elements in the source XML. They are deal-code0 and deal-code1
  2. dealer-code-name is an element, not an attribute.

Your XPATH currently matches dealer-code elements with @dealer-code-name='0'. Since there are no dealer-code elements and there are no dealer-code-name attributes, it never matches and does not suppress the content.

You need to adjust your XPATH to match the deal-code elements similar to how you are in the other template and add an additional predicate filter for child elements dealer-code-name with a value of 0. Additionally, since both of your templates have similar matching logic, they may get the same priority level. You may need to bump up the priority of this redaction template, so that it "wins" against the more generic match:

 <xsl:template match="*[starts-with(name(), 'deal-code') and dealer-code-name='0']" priority="1"/>


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="@* | node()">
     <xsl:copy>
       <xsl:apply-templates select="@* | node()"/>
     </xsl:copy>
  </xsl:template>
  <xsl:template match="*[starts-with(name(), 'deal-code')]">
     <xsl:if test="dealer-code-name!='0']">
       <xsl:element name="dealer-code">
       <xsl:apply-templates/>
       </xsl:element>
     </xsl:if>
  </xsl:template>
</xsl:stylesheet>

you have no element dealer-code in your input xml, but you can filter when your processing elements starting with deal-code by testing if they have a child element dealer-code-namewhich value is 0

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜