Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xsl:template transformation packs text nodes to the beginning #109

Open
jrutila opened this issue Oct 16, 2024 · 3 comments
Open

xsl:template transformation packs text nodes to the beginning #109

jrutila opened this issue Oct 16, 2024 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@jrutila
Copy link

jrutila commented Oct 16, 2024

This test case will show the problem. The output is now XYtest1 even though it should be Xtest1Y. I think it is because the text nodes get siblingPosition of -1 and the xsl:value-of gets bigger than 0. Then, when it is rendering, it sorts the siblings by siblingPosition.

    it('XSLT template with text on both sides', async () => {
        const xmlString = `<root>
          <test name="test1">This text lost</test>
        </root>`;

        const xsltString = `<?xml version="1.0"?>
          <xsl:stylesheet version="1.0">
            <xsl:template match="/">
              <span>X<xsl:value-of select="test/@name" />Y</span>
            </xsl:template>
          </xsl:stylesheet>`;

        const expectedOutString = `<span>Xtest1Y</span>`;

        const xsltClass = new Xslt();
        const xmlParser = new XmlParser();
        const xml = xmlParser.xmlParse(xmlString);
        const xslt = xmlParser.xmlParse(xsltString);

        const outXmlString = await xsltClass.xsltProcess(xml, xslt);

        assert.equal(outXmlString, expectedOutString);
    });
@leonelsanchesdasilva leonelsanchesdasilva self-assigned this Oct 17, 2024
@leonelsanchesdasilva leonelsanchesdasilva added the bug Something isn't working label Oct 17, 2024
@leonelsanchesdasilva
Copy link
Collaborator

@jrutila Thanks again for this new test. I added to our unit tests as well.

This test fails with the following:

    Difference:

    - Expected
    + Received

    - <span>Xtest1Y</span>
    + <span>Ytest1</span>

But the online transformer returns something else:

<span>XY</span>

This happens because the resulting XML doesn't necessarily retain text from the input, if not explicitly mentioned in the template.

Can you please validate if I should implement the behavior from the online transformer? It utilizes XSL implementation in Java.

leonelsanchesdasilva added a commit that referenced this issue Oct 17, 2024
@jrutila
Copy link
Author

jrutila commented Oct 17, 2024

Change the value-of line to

span>X<xsl:value-of select="//test/@name" />Y</span>

@leonelsanchesdasilva
Copy link
Collaborator

@jrutila This problem happens due to this project still not having template precedence implemented. We have a unit test that describes the problem very well. So far, the logic to resolve this works good with one child text node, but not with multiple nodes: https://github.com/DesignLiquido/xslt-processor/blob/main/src/xslt/xslt.ts#L943

Besides the template precedence (which resolves an issue when a more restricted template comes before a least restricted template), I need to think about a logic that writes text nodes differently when they are in a template. One of my initial ideas was to pass a fragment node to write the children of that node, separating commonLogicTextNode into two methods: one that works in a traditional pass, outside of a template (in this case, simply appending nodes to the parent node), and one inside of the template, overwriting text nodes when needed.

As time is being scarce on my end, I would need some time to think about a good solution on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants