如果祖先的属性使用xsl保存特定值,如何删除属性和元素

时间:2014-12-04 13:52:08

标签: xslt ancestor remove-if

我正在努力解决以下问题: 在下面的XML中,如果属性嵌套在同样包含属性restrict =“restrict”的元素中,我需要删除属性restrict =“restrict”。如果它嵌套在包含属性restrict =“restrict”的元素中,我还需要删除元素限制。但是,如果在祖先不包含属性restrict =“restrict”的嵌套元素上出现restrict =“restrict”,我需要保留它。限制元素也是如此。如果它没有嵌套在restrict元素中或者没有restrict =“restrict”属性的元素中,我需要保留它。

<book hasrestrict="yes"> 
<story> <part partno="1"> <parttitle>Title of the Part</parttitle> 
<chapter chapno="11"> <chaptertitle>Title of the Chapter</chaptertitle> 
<section id="id3321234" secno="23">
<sectiontitle>Title of the Section</sectiontitle> 
<toc/> 
<subsection1 restrict="restrict">
<date>(09-23-2012)</date> 
<title>Subsection Title</title> 
<p>Text that makes up the paragraph of the subsetion1. <restrict>This information is  
restricted.</restrict></p> 
<p restrict="restrict">Here is some text in another paragraph that is
restricted. The restrict attribute of the paragraph needs to be
removed because a restrict attribute is already specified for
subsection1. Everything that appears within the element of subsection
1 is already restricted, so I need to remove the unnecessary restrict
attribute from the paragraph because it is causing havoc when my
publishing system tries to format the document.</p>
<subsection2><title>Title of Subsection2</title> 
<p>This is text that appears in a subsecion2 paragraph. 
<list><li>This is an item in a list <restrict>that has restricted content</restrict></li>
<li>Second item</li> 
<li>Third item</li></list></p> 
<subsection3 restrict="restrict">
<title>Title of Subsection3</title> 
<p>Text appearing in a paragraph in subsction 3 
<table frame="all"> <tgroup cols="3" colsep="1" rowsep="1"> 
<colspec colname="col1"/> <colspec colname="col2"/> 
<colspec colname="col3"/>
<thead><row><entry>Entry1</entry>
<entry>Entry2</entry>
<entry>Entry3 <restrict>with restricted information</restrict></entry></row></thead>
<tbody><row><entry restrict="restrict">text</entry>
<entry>text</entry>
<entry>text</entry></row>
</tbody></tgroup></table></p></subsection3></subsection2></subsection1>
<subsection1><date>(09-23-2012)</date> 
<title>Subsection Title</title>
<p>Text that makes up the paragraph of the subsetion1. <restrict>This information is
restricted.</restrict></p> 
<p restrict="restrict">Here is some text in another paragraph that is
restricted. </p> 
<subsection2 restrict="restrict"><title>Title of Subsection2</title>
<p>This is text that appears in a subsecion2 paragraph.</p>
</subsection2></subsection1></section></chapter></part></story></book>

我是xsl的新手,并试图编写翻译,但我没有太多运气。

期望的输出应该如下所示:

<book hasrestrict="yes">
<story>
<part partno="1">
<parttitle>Title of the Part</parttitle>
<chapter chapno="11">
<chaptertitle>Title of the Chapter</chaptertitle>
<section id="id3321234" secno="23">
<sectiontitle>Title of the Section</sectiontitle>
<toc/>
<subsection1 restrict="restrict"><date>(09-23-2012)</date>
<title>Subsection Title</title>
<p>Text that makes up the paragraph of the subsetion1. This information is restricted.</p>
<p>Here is some text in another paragraph that is restricted. The restrict attribute of the paragraph needs to be removed because a restrict attribute is already specified for subsection1. Everything that appears within the element of subsection1 is already restricted, so I need to remove the unnecessary restrict attribute from the paragraph because it is causing havoc when my publishing system tries to format the document.</p>
<subsection2><title>Title of Subsection2</title>
<p>This is text that appears in a subsecion2 paragraph.
<list>
<li>This is an item in a list that has restricted content</li>
<li>Second item</li>
<li>Third item</li></list></p>
<subsection3><title>Title of Subsection3</title>
<p>Text appearing in a paragraph in subsction 3
<table frame="all">
<tgroup cols="3" colsep="1" rowsep="1">
<colspec colname="col1"/>
<colspec colname="col2"/>
<colspec colname="col3"/>
<thead><row><entry>Entry1</entry>
<entry>Entry2</entry>
<entry>Entry3 with restricted information</entry></row></thead>
<tbody><row>text</entry>
<entry>text</entry>
<entry>text</entry></row></tbody></tgroup></table></p></subsection3></subsection2></subsection1>
<subsection1><date>(09-23-2012)</date>
<title>Subsection Title</title><p>Text that makes up the paragraph of the subsetion1. <restrict>This information is restricted.</restrict></p>
<p restrict="restrict">Here is some text in another paragraph that is restricted. </p>
<subsection2 restrict="restrict"><title>Title of Subsection2</title><p>This is text that appears in a subsecion2 paragraph.</p></subsection2></subsection1></section></chapter></part></story></book>

以下是我尝试的代码:

<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="@restrict">
  <xsl:if test="ancestor::*[@restrict='restrict']">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:if>
</xsl:template>

<xsl:template match="restrict">
  <xsl:if test="ancestor::*[@restrict='restrict']">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:if>
</xsl:template>

<xsl:template match="restrict"> 
  <xsl:if test="ancestor::restrict">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:if>
</xsl:template>     
</xsl:transform>

这对我不起作用。我收到一条错误说明

“警告org.xml.sax.SAXParseException:从属性节点开始的子轴永远不会选择任何内容”

我真的不知道该怎么做。任何建议(和解释)都会很大 赞赏。

2 个答案:

答案 0 :(得分:1)

当您使用身份模板时,您并不需要为您希望保留的元素或属性编写额外的逻辑;他们是restrict还是<xsl:template match="../ancestor::*[@restrict='restrict']]" /> 。您只需要为要删除的内容添加模板。

你说&#34; 需要删除属性restrict =&#34;限制&#34;如果属性嵌套在同样包含属性restrict =&#34; restrict &#34;的元素中。那么,执行此操作的模板就是这样:

restrict

(这里..是忽略当前具有当前<xsl:template match="restrict[ancestor::*[@restrict='restrict']]" /> 元素的元素)

如果它嵌套在包含属性restrict =&#34; restrict&#34;。&#34;的元素中,则删除元素限制&#34;看起来像这样

restrict

话虽如此,你提到了保留<xsl:template match="@restrict[../ancestor::restrict or ../ancestor::*[@restrict='restrict']]" /> <xsl:template match="restrict[ancestor::restrict or ancestor::*[@restrict='restrict']]" /> 元素,如果它们没有嵌套在一个限制元素中,或者没有嵌套在一个没有限制的元素内,那么限制&#34;属性。在这种情况下,模板可能需要如下所示:

<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@* | node()">
      <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="@restrict[../ancestor::restrict or ../ancestor::*[@restrict='restrict']]" />        
    <xsl:template match="restrict[ancestor::restrict or ancestor::*[@restrict='restrict']]" /> 
</xsl:transform>

试试这个XSLT

{{1}}

答案 1 :(得分:0)

如果我理解正确,你想做:

XSLT 1.0

<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:strip-space elements="*"/>

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

<!-- remove the attribute restrict="restrict" if the attribute is nested within an element that also contains an attribute restrict="restrict". -->
<xsl:template match="@restrict[.='restrict'][parent::*/ancestor::*/@restrict='restrict']"/>


<!-- remove the element restrict if it is nested within an element containing an attribute restrict="restrict".  -->
<xsl:template match="restrict[ancestor::*/@restrict='restrict']">
    <xsl:apply-templates select="@*|node()"/>
</xsl:template>

</xsl:stylesheet>