|
It's much easier to always have the outer container tag, no matter how many tags are inside it. That way, you can enumerate all the Topics with a simple /TopicList/Topic XPath query. Don't take shortcuts on your schema just to save yourself 5 seconds of typing.
|
|
|
|
|
This is easy to do in the Schema, the software that uses it is where the complication comes in with this type of structure. Never understood why someone would want to do this, but it can be done.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="Topic">
</xs:complexType>
<xs:complexType name="TopicList">
<xs:sequence>
<xs:element type="Topic" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RootNode">
<xs:choice>
<xs:element type="Topic"></xs:element>
<xs:element type="TopicList"></xs:element>
</xs:choice>
</xs:complexType>
<xs:element type="RootNode"></xs:element>
</xs:schema>
Your root node is of type "RootNode", which is a Choice , meaning it will accept either a "Topic" or a "TopicList". And "TopicList" is a sequence of "Topics".
|
|
|
|
|
thanks a lot for the reply!
BoneSoft wrote: the complication comes in with this type of structure. Never understood why someone would want to do this, but it can be done.
OK OK, I get the hints
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
Linkify! || Fold With Us! || sighist
|
|
|
|
|
IMHO, if the concept of TopicList exists and the info meaningful, it should be represented explicitly.
We're the regulators that de-regulate
We're the animators that de-animate
Fold with us! ¤ flickr
|
|
|
|
|
This is my first attempt at making "real" modifications to an xsl stylesheet, and I'm completely stumped now. This is probably something simple, so try not to laugh too much.
Here's the code I'm having trouble with:
<xsl:variable name="reportName">
<xsl:value-of select="NodeName"/>
</xsl:variable>
<xsl:value-of select="$reportName"/>
<!--Does not work-->
<xsl:value-of select="//PageXML/Document/report[name = $reportName]/regionalFlag"/>
<!--Works fine-->
<xsl:value-of select="//PageXML/Document/report[name = 'workordertime']/regionalFlag"/>
Now, I'm printing the value of $reportName every time and it IS coming up as workordertime, but for some reason it isn't selecting any value. If I hardcode the report name, however, it DOES work... so the basic XSL is right. I'm fairly sure that's how I'd use a variable to do the select, as the same technique is used in other places... I have no idea what could be causing the problem...
|
|
|
|
|
Try using parameter instead of variable
Sincerely,
Elina
Life is great!!!
Enjoy every moment of it!
|
|
|
|
|
Parameters are passed into the stylesheet though right? That won't help here, I'm running through a list of reports from the source sheet, and trying to find configuration information for each report also in the source sheet... so it's not something I can just pass in on the command line.
|
|
|
|
|
You define the parameter the same way as you devine the variable.
Just write: xsl:parameter.
I have no idea, if it is passed throught stylesheets. sorry
Sincerely,
Elina
Life is great!!!
Enjoy every moment of it!
|
|
|
|
|
I get an error saying that xsl:parameter is an invalid child element when I try to use it.
|
|
|
|
|
Sorry, it is xsl:param , not xsl:parameter
Sincerely,
Elina
Life is great!!!
Enjoy every moment of it!
|
|
|
|
|
That gives me a syntax error too, which says the same basic thing only with fewer words.
|
|
|
|
|
This actually works just fine. Could you please elaborate on what "name" is? I assume it's a child element of report. There's nothing that I can see would be wrong with this code. Could you also please give some indication on what that non-working statement is returning in the output?
|
|
|
|
|
Yes, I'm pretty sure name is a child element of report. I'm not at work now though so I can't look. It SHOULD print out "true" when it gets to the workordertime report but I'm getting nothing at all. It prints out "true" fine when I hardcode 'workordertime' instead of using the $reportname variable though.
I can look at the source xml tomorrow and post it, I didn't have a chance to work on that today anyway.
|
|
|
|
|
One thing that I thought of is that there may be some whitespace in the variable that is not in your hard coded 'workordertime'. You might want to try this:
<xsl:variable name="reportName">
<xsl:value-of select="normalize-space(NodeName)"/>
</xsl:variable>
|
|
|
|
|
Normalize-space didn't work.
Here's the relevant part of the source XML:
<PageXML>
<Ident>14</Ident>
<PageIdent>266</PageIdent>
<Name>test</Name>
<Document>
<report>
<name>workordertime</name>
<regionalFlag>true</regionalFlag>
</report>
</Document>
</PageXML>
The whole document would be way too large to post...
|
|
|
|
|
Could you find the NodeName node in the XML and post what that looks like?
|
|
|
|
|
Here's a little more of the original xsl that is failing. I thought this would be a simple syntax error or something so didn't post the surrounding loop.
Here it is:
<xsl:for-each select="//node[NodeParentNodeIdent = $ThisIdent][PagePublished = 'True']">
<xsl:if test="NodeIdent = //LinkedPageDetail/PageIdent">
<xsl:copy-of select=""/>
<xsl:variable name="reportName" >
<xsl:value-of select="normalize-space(NodeName)"/>
</xsl:variable>
<xsl:value-of select="$reportName"/>
<xsl:value-of select="//PageXML/Document/report[name = $reportName]/regionalFlag"/>
<br />
<!--<xsl:value-of select="//PageXML/Document/report[name = 'workordertime']/regionalFlag"/>-->
<xsl:variable name="regionFlag">
<xsl:value-of select="//PageXML/Document/report1"/>
</xsl:variable>
<p><a href="{PageBreadcrumb}?UseRegions={$regionFlag}" target="_blank"><xsl:value-of select="PageTitle" disable-output-escaping="yes"/></a></p>
</xsl:if>
</xsl:for-each>
And here is the current node of that loop when it should find the workordertime report and print it's value:
<node>
<TreeIdent>2</TreeIdent>
<NodeIdent>274</NodeIdent>
<TreeName>Synergy - ePortal</TreeName>
<NodeName>workordertime</NodeName>
<NodeLevel>3</NodeLevel>
<NodeParentNodeIdent>273</NodeParentNodeIdent>
<SiteIdent>2</SiteIdent>
<SiteSortOrder>1</SiteSortOrder>
<SiteName>Synergy - ePortal</SiteName>
<SiteDescription>Synergy - ePortal</SiteDescription>
<SiteTitle>Web Site - Synergy - ePortal - QuantumCMS</SiteTitle>
<SitePublished>True</SitePublished>
<PageShowInNav>False</PageShowInNav>
<PageBreadcrumb>/Home/Reports/summaries/workordertime</PageBreadcrumb>
<PageIdent>274</PageIdent>
<PageSortOrder>1</PageSortOrder>
<PageName>workordertime</PageName>
<PageDescription>Workorder Time</PageDescription>
<PageTitle>Workorder Time</PageTitle>
<PageLevel>3</PageLevel>
<PageLeftBound>125</PageLeftBound>
<PageRightBound>126</PageRightBound>
<ParentNodeIdent>273</ParentNodeIdent>
<ParentPageIdent>273</ParentPageIdent>
<PageTypeIdent>1</PageTypeIdent>
<PageTypeName>Document</PageTypeName>
<PageSummary></PageSummary>
<PageReleaseDate>2006-10-03T00:00:00.0000000-04:00</PageReleaseDate>
<PageRevision>1</PageRevision>
<PageCached>False</PageCached>
<PageSearched>False</PageSearched>
<PageRequired>False</PageRequired>
<PagePublished>True</PagePublished>
<PageActive>True</PageActive>
<PageURL>/Home/Reports/summaries/workordertime</PageURL>
</node>
It's basically inside of another node just like it, and this for-each loop is an inner loop from another for-each loop.
|
|
|
|
|
Well, I thought maybe NodeName had something strange about it, but that doesn't seem to be the case. The variable looks fine and I recreated very similar XML and XSL files and it worked without a problem. There are two things I can think of to try. First, declare your variable like this:
<xsl:variable name="reportName" select="NodeName"/>
But I doubt that will have an effect. The other thing is to comment out that if statement in the loop. It may be correct, but it looks like a really odd syntax. NodeIdent = //LinkedPageDetail/PageIdent looks to me like you're comparing the contents of NodeIdent to a list of nodes PageIdent anywhere in the document. It may be putting you in a different position in the XML document unexpectedly.
Just grasping at straws really.
|
|
|
|
|
Actually, <xsl:variable name="reportName" select="NodeName"/> worked!
Thanks for your help!
|
|
|
|
|
[ This has been answered ]
My path is to ( my conditional )
/Events/CompanyABC/Transaction/ProductList/Product/Event/Code = 435
The actual node I want:
/Events/CompanyABC/Transaction/ProductList/Product/LoanList/Loan/ReturnedType
I tried this:
//Events/CompanyABC/Transaction/ProductList/Product[./Event/Code = '435']/LoanList/Loan/ReturnedType
But it doesn't return anything.
How can I combine the conditional into the xpath statement. This has to be one string, I can't split it.
Thanks,
Nick
-- modified at 13:04 Tuesday 24th October, 2006
--------------------------------------------------------
1 line of code equals many bugs. So don't write any!!
My mad coder blog
|
|
|
|
|
Ista wrote: /Events/CompanyABC/Transaction/ProductList/Product/Event/Code = 435
Is Code an attribute or an element? If it's an attribute, prefix it with @ in the query to indicate that it's an attribute name.
|
|
|
|
|
lol. Nah thier all elements.
And actually it worked. I just had the wrong events.
Thanks for helping tho
--------------------------------------------------------
1 line of code equals many bugs. So don't write any!!
My mad coder blog
|
|
|
|
|
Given the following XSD File
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Item">
<xs:complexType mixed="true">
<xs:attribute name="uri" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="Collection">
<xs:complexType>
<xs:sequence>
<xs:element ref="Item" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Structure">
<xs:complexType>
<xs:sequence>
<xs:annotation>
<xs:documentation>Sequence</xs:documentation>
</xs:annotation>
<xs:choice>
<xs:annotation>
<xs:documentation>Choice Element</xs:documentation>
</xs:annotation>
<xs:element ref="Item">
<xs:annotation>
<xs:documentation>Singular Item (Doesn't have to be a reference)</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="Collection">
<xs:annotation>
<xs:documentation>Collection of Items (Must be a Reference)</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
<xs:element name="Count" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
As you can see there is a **choice element ** which has a choice of either a singular Item or a collection of Items. When you use XSD.exe to create the classes in .net you get the following:
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Collection", typeof(Item[]))]
[System.Xml.Serialization.XmlElementAttribute("Item", typeof(Item))]
public object Item {
get {
return this.itemField;
}
set {
this.itemField = value;
}
}
So .NET xsd.exe recognises it’s a choice element and creates the Serialization correctly.
The problem occurs when you try and create a “WebReference” to the web service in a client application. If you look at the reference.cs it has an incorrect version:
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Collection", typeof(ArrayOfItemItem[]))]
[System.Xml.Serialization.XmlElementAttribute("Item", typeof(TestXSDResultItem))]
public object Item {
get {
return this.itemField;
}
set {
this.itemField = value;
}
}
As a result if you try and consume the web service by setting the choice element to a collection and returning that through the WS back into the client application you’ll end up with an empty collection always.
Can anyone help. I've a more detailed explanation and an example application if you want to email me and get that?
All Comments appreciated.
Dave
|
|
|
|
|
I'm not sure off hand from your description if this will help or not, but I have a tool that builds code from XSD, but in the case of a Choice, I generate a property for each choice on the class. The code generated is XML serializable. You might want to grab a copy of the trial and see if it does what you need.
You can try it on-line here[^], or you can download the trial here[^]
Hope that helps.
|
|
|
|
|
Got a fix from Microsoft in the end. Horah!
FIX: A deserialized object may contain null objects when you deserialize an object from XML in the .NET Framework 2.0
http://support.microsoft.com/kb/918298
|
|
|
|