0

I am struggling with the following issue: In the below XML, I need to remove the attribute restrict="restrict" if the attribute is nested within an element that also contains an attribute restrict="restrict". I also need to remove the element restrict if it is nested within an element containing an attribute restrict="restrict". However, if a restrict="restrict" appears on a nested element whose ancestor does not contain an attribute restrict="restrict", I need to keep it. The same goes for the restrict element. I need to keep it if it is not nested in a restrict element or within an element that does not have the restrict="restrict" attribute.

<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>

I am new to xsl, and have attempted to write the translation, but I am not having much luck.

The desired out put should look like this:

<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>

Here is the code I have attempted:

<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>

This is not working for me. I receive an error stating

"WARNING org.xml.sax.SAXParseException: The child axis starting at an attribute node will never select anything"

I really don't know how to go about doing this. Any suggestions (and explanation) would be greatly appreciated.

4

2 回答 2

1

当您使用身份模板时,您实际上不需要为希望保留的元素或属性编写额外的逻辑;不管他们是restrict不是。您只需要为要删除的内容添加模板。

您说“如果属性嵌套在还包含属性 restrict="restrict" 的元素中,则需要删除属性 restrict="restrict "。好吧,执行此操作的模板如下所示:

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

(这里的 .. 是忽略具有当前元素的当前restrict元素)

并且要“删除元素限制,如果它嵌套在包含属性限制=“限制”的元素中。 ”,模板看起来像这样

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

话虽如此,您提到restrict如果元素没有嵌套在限制元素中或没有嵌套在没有限制=“限制”属性的元素中,则保留元素。在这种情况下,模板可能需要如下所示:

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

试试这个 XSLT

<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>
于 2014-12-04T14:11:02.660 回答
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>
于 2014-12-04T16:05:56.887 回答