Pregunta

I have gone all over the web looking for an answer to this, and have not been able to find one anywhere.

I'm trying to build a web form that uses XSLT to generate XML data. I'm basing it on other forms that do the same thing, and have gotten small test structures to work fine. However, I am running into all sorts of problems when I try to map it to repeated elements.

Here's a quick overview of what I have. I have an XSLT file that looks similar to this (disclaimer: lines excluded for brevity; also, these are NOT the actual field names):

<someForm:Name></someForm:Name>
<someForm:Address></someForm:Address>
<someForm:Plan>
    <someForm:Step></someForm:Step>
    <someForm:Description></someForm:Description>
</someform:Plan>

I also have an associated schema that looks like this:

<xs:element name="Name" />
<xs:element name="Address" />
<xs:element name="Plan" maxOccurs="10">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Step" />
            <xs:element name="Description" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

Make note of the "maxOccurs='10'" in the Plan element! This is where I'm having problems!

I wrote a form (again, based on other, working forms) that looks like this:

<input type="text" id="getName" xpath="/*[local-name()='Name']">
<input type="text" id="getAddress" xpath="/*[local-name()='Address']">
<table>
    <tr><th>Step</th><th>Description</th></tr>
    <tr>
        <td><input type="text" id="getStep1" xpath="/*[local-name()='Plan']/*[local-name()='Step']"></td>
        <td><input type="text" id="getDesc1" xpath="/*[local-name()='Plan']/*[local-name()='Description']"></td>
    </tr>
</table>

This works fine; I am able to submit data, and it creates the XML as I want.

However, here is my problem: I am trying to write my setup so it can accommodate up to ten rows (as per the maxOccurs setting). It will NOT work when I try to do this:

    <tr>
        <td><input type="text" id="getStep1" xpath="/*[local-name()='Plan']/*[local-name()='Step']"></td>
        <td><input type="text" id="getDesc1" xpath="/*[local-name()='Plan']/*[local-name()='Description']"></td>
    </tr>
    <tr>
        <td><input type="text" id="getStep2" xpath="/*[local-name()='Plan']/*[local-name()='Step']"></td>
        <td><input type="text" id="getDesc2" xpath="/*[local-name()='Plan']/*[local-name()='Description']"></td>
    </tr>

This gives me all sorts of problems, depending on how I tweak it. Sometimes, it does not save any data (for Step and Description); sometimes, it saves the same data for both rows.

I have not been able to find any documentation that explains how this works. I've tweaked the XSLT, HTML, and schema, all to no avail. And this is frustrating the crap out of me.

Does anyone have any insight as to how to solve this?

Note: this is directly related to another question that I asked earlier: Creating XSLT nodes dynamically/multiple XSLT nodes

Thanks in advance for any assistance . . .

¿Fue útil?

Solución

Here's how I finally got this to work:

    <tr>
        <td><input type="text" id="getStep1" xpath="/*[local-name()='Plan'][1]/*[local-name()='Step']"></td>
        <td><input type="text" id="getDesc1" xpath="/*[local-name()='Plan'][1]/*[local-name()='Description']"></td>
    </tr>
    <tr>
        <td><input type="text" id="getStep2" xpath="/*[local-name()='Plan'][2]/*[local-name()='Step']"></td>
        <td><input type="text" id="getDesc2" xpath="/*[local-name()='Plan'][2]/*[local-name()='Description']"></td>
    </tr>

If you look at the xpath, notice the [1] and [2] after "Plan." When I included those with the xpath, it worked with no problem.

Otros consejos

You need to specify which Plan element you want for each tr, i.e. the first tr needs to get the first Plan, and so on. To do this you can use the position() function in your [local-name()='Plan'] predicate, e.g.:

[local-name()='Plan' and position()=1]

for the first tr

[local-name()='Plan' and position()=2]    

for the second tr, and so on.

This should get you started but you could probably also make your code smarter by looping to output tr elements.

The example XPath in your question would return all Step or Description elements as you are specifying a node-tree i.e. collection of nodes. The position function allows you to select a single node in the node-tree.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top