QuickFix for removing whitespaces

This should cover W3C XML Schema, Relax NG and DTD related problems.
DavidK
Posts: 2
Joined: Mon May 13, 2024 1:53 pm

QuickFix for removing whitespaces

Post by DavidK »

Hello,

I am still new to creating schematron rules and currently trying to develop a quickfix that removes all whitespace within a <p> tag. The schematron rule works correctly, but the quickfix also eliminates spaces before and after inline elements. Is there a simple solution for this, or do I need to reconstruct the p-tag using the concat function?
I would be grateful for any help.

Code: Select all

  <pattern id="normalize-p-tag">
    <rule context="p">
      <assert test="normalize-space(.) = ." sqf:fix="normalize">whitespaces found</assert>
      <sqf:fix id="normalize">
        <sqf:description>
          <sqf:title>normalize p-tag</sqf:title>
        </sqf:description>
        <sqf:replace match="node()" select="normalize-space(.)"/>
      </sqf:fix>
    </rule>
  </pattern>
tavy
Posts: 379
Joined: Thu Jul 01, 2004 12:29 pm

Re: QuickFix for removing whitespaces

Post by tavy »

Hello,

I believe you can create a quick fix that normalizes spaces while adding a space before and after the text. For the first and last pieces of text, you can add a space after and before them, respectively.

Code: Select all

<sqf:fix id="normalize">
    <sqf:description>
        <sqf:title>normalize p-tag</sqf:title>
    </sqf:description>
    <sqf:replace match="text()[position() = 1]" select="concat(normalize-space(), ' ')"/>
    <sqf:replace match="text()[position() != 1 and position() != last()]" select="concat(' ', normalize-space(), ' ')"/>
    <sqf:replace match="text()[position() = last()]" select="concat(' ', normalize-space())"/>
</sqf:fix>
Best Regards,
Octavian
Octavian Nadolu
<oXygen/> XML Editor
http://www.oxygenxml.com
DavidK
Posts: 2
Joined: Mon May 13, 2024 1:53 pm

Re: QuickFix for removing whitespaces

Post by DavidK »

Hi Octavian,

thank you for your solution! I’ve already learned something from it.

I added the line <sqf:replace match="text()" select="normalize-space()"/> at the beginning to ensure that even <p> tags without inline elements are normalized. Also, because text within <p>tags without any inline elements would be position = 1 and position = last at the same time (correct me if I'm wrong) and your quickfix would add spaces in that case, I added a second condition in your first and last match statement.

Code: Select all

  <sqf:fix id="normalize">
        <sqf:description>
          <sqf:title>normalize p-tag</sqf:title>
        </sqf:description>

        <sqf:replace match="text()" select="normalize-space()"/>
        
        <sqf:replace match="text()[position() = 1 and position() != last()]" select="concat(normalize-space(), ' ')"/>

        <sqf:replace match="text()[position() != 1 and position() != last()]" select="concat(' ', normalize-space(), ' ')"/>
        
        <sqf:replace match="text()[position() = last() and position() != 1]" select="concat(' ', normalize-space())"/>
      </sqf:fix> 

Even though the logic seems fine to me, it still doesn’t quite work as expected.

This already works:
<p>_text_</p> :arrow: <p>text</p>
<p>_text_<xref></xref>_text_</p> :arrow: <p>text_<xref></xref>_text</p>

This doesnt work:
<p>_text_<xref></xref></p> :arrow: <p>text<xref></xref></p> (no space before the inline element)
<p>_text_<xref></xref>_text_<xref></xref></p> :arrow: <p>_text_<xref></xref>_text<xref></xref></p> (space after the second text element gets removed)

Do you see, why it's not working?
Last edited by DavidK on Thu Oct 31, 2024 10:15 am, edited 1 time in total.
tavy
Posts: 379
Joined: Thu Jul 01, 2004 12:29 pm

Re: QuickFix for removing whitespaces

Post by tavy »

Hi David,

If you have inline elements at the beginning and end of a paragraph, you need to verify the position of the nodes within the paragraph. Additionally, check if the node is a text node. It should look something like this:

Code: Select all

<sqf:fix id="normalize">
    <sqf:description>
        <sqf:title>normalize p-tag</sqf:title>
    </sqf:description>
    <sqf:replace match="node()[position() = 1][self::text()]" select="concat(normalize-space(), ' ')"/>
    <sqf:replace match="node()[position() != 1 and position() != last()][self::text()]" select="concat(' ', normalize-space(), ' ')"/>
    <sqf:replace match="node()[position() = last()][self::text()]" select="concat(' ', normalize-space())"/>
</sqf:fix>
Best Regards,
Octavian
Octavian Nadolu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply