I have a GridView populated from an xml file, which has the following structure:
<menu>
<item id="1" name="home" page="default.aspx">
*{...some stuff...}*
<item>
<item id="2" name="content" page="content.aspx">
*{...some stuff...}*
<item>
<item id="3" name="user" page="user.aspx">
*{...some stuff...}*
<item>
<menu>
As you can reckon, it's the menu of my application.
If i just associate that file to an xmldatasource and then to a GridView, it shows (correctly) a grid like this:
id name page
1 home default.aspx
2 content content.aspx
3 user user.aspx3 user user.aspx
How do I set the xPath query to only show name attribute/field?
I've tried those:
menu/item#name
menu/#name
//#name
but didn't work
I have a GridView populated from an
xml file, which has the following
structure:
<menu>
<item id="1" name="home" page="default.aspx">
*{...some stuff...}*
<item>
<item id="2" name="content" page="content.aspx">
*{...some stuff...}*
<item>
<item id="3" name="user" page="user.aspx">
*{...some stuff...}*
<item>
<menu>
This is not a well-formed XML file -- an ending tag must have the sintax </tag> and there are no ending tags at all in the above text.
How do I set the xPath query to only
show name attribute/field?
I've tried those:
menu/item#name
menu/#name
//#name
is syntactically invalid: location steps must start with the / character and there is no / character between item and #name.
is syntactically valid but is asking to select all name attributes of all menu elements that are children of the current node. Unfortunately, menu has no name attributes.
should select nodes, but given the text above isn't at all a well-formed XML document, this explains the negative result. Also, this selects all name attributes in the whole document, regardles on which element they are -- this is not exactly what you want, regardless of the fact that on a wellformed document of this type this might select the nodes you want.
Solution:
Step1: Correct your XML document:
<menu>
<item id="1" name="home" page="default.aspx">
*{...some stuff...}*
</item>
<item id="2" name="content" page="content.aspx">
*{...some stuff...}*
</item>
<item id="3" name="user" page="user.aspx">
*{...some stuff...}*
</item>
</menu>
Step2: Use one of the following XPath expressions (there are even more that would select the wanted nodes):
/menu/item/#name
or
/*/item/#name
or
/*/*/#name
or
//#name
Related
I am using BaseX to store XML data with multiple item nodes in the following format:
<root>
<item id="Root" parent_id="0" type="folder">
<content>
<name>Root</name>
</content>
</item>
<item id="One" parent_id="Root" type="file">
<content>
<name>First File in the Tree</name>
</content>
</item>
<item id="Two" parent_id="Root" type="file">
<content>
<name>Second File in the Tree</name>
</content>
</item>
</root>
I am trying to update the parent_id on one of the 'item' nodes to another item node's id attribute.
The tree before running the XQuery expression:
Root
∟ First File in the Tree
∟ Second File in the Tree
I am trying to figure out the correct XQuery expression to change the parent of one of the items from root to "one" item, so that my tree now looks like this:
Expected result tree:
Root
∟ First File in the Tree
∟ Second File in the Tree
Since the attribute parent_id controls this, I am looking to update exactly that.
If all you want to do is to update the #parent_id attribute, use a simple updating query like
replace value of node //item[#id='Two']/#parent_id with 'One'
But: this wouldn't actually change the XML tree, but only the one you're representing in XML (although I believe that this is what your question was about). A more XML-like approach to store the tree would be directly mapping the tree you want to have to XML:
<root>
<item id="Root" type="folder">
<content>
<name>Root</name>
</content>
<item id="One" type="file">
<content>
<name>First File in the Tree</name>
</content>
<item id="Two" type="file">
<content>
<name>Second File in the Tree</name>
</content>
</item>
</item>
</item>
</root>
Or even more concise, holding the same information:
<folder id="Root" name="Root">
<file id="One" name="First File in the Tree">
<file id="Two" name="Second File in the Tree" />
</file>
</folder>
I'm trying to do a map on BizTalk 2013, and I'm blocked at this mapping problem (using mapper):
Input message:
<DetailsResponse>
<HeaderDetails>
<DocumentNumber>322</DocumentNumber>
</HeaderDetails>
<ItemDetails>
<item>
<DocumentNumber>322</DocumentNumber>
<ItemNumber>1</ItemNumber>
<MaterialNumber>40</MaterialNumber>
<Description>random description 1</Description>
</item>
<item>
<DocumentNumber>322</DocumentNumber>
<ItemNumber>2</ItemNumber>
<MaterialNumber>41</MaterialNumber>
<Description>random description 2</Description>
</item>
</ItemDetails>
<ScheduleDetails>
<item>
<DocumentNumber>322</DocumentNumber>
<ItemNumber>1</ItemNumber>
<ConfirmedQuantity>2.000</ConfirmedQuantity>
</item>
<item>
<DocumentNumber>322</DocumentNumber>
<ItemNumber>2</ItemNumber>
<ConfirmedQuantity>3.000</ConfirmedQuantity>
</item>
</ScheduleDetails>
</DetailsResponse>
Intended output message:
<Response>
<Data>
<Items>
<Item>
<LineNumber>
<Internal>1</Internal>
</LineNumber>
<ConfirmedQuantity>
<Value>2</Value>
</ConfirmedQuantity>
<Article>
<Number>40</Number>
<Description>random description 1</Description>
</Article>
</Item>
<Item>
<LineNumber>
<Internal>2</Internal>
</LineNumber>
<ConfirmedQuantity>
<Value>3</Value>
</ConfirmedQuantity>
<Article>
<Number>41</Number>
<Description>random description 2</Description>
</Article>
</Item>
</Items>
</Data>
</Response>
I want to map ItemsDetails and ScheduleDetails to Item, by "merging" their data based on ItemNumber. I already tried a lots of things but wasn't able to do it yet.
I couldn't find any example about this.Does this pattern have any particular name?
If anyone has any idea that they can share, it would be appreciated.
The only way I can think to maybe get this working with Functoids is to link ItemDetails and ScheduleDetails with one or more Looping Functoids and using an Equal Functoid to filter the ScheduleDetails based on the current ItemDetail ItemNumber.
It that doesn't work out, your only other option is custom Xslt. A Call Template would be pretty straight forward.
If you convert your map to vanilla XSLT, then the mapping becomes straightforward :
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="itemSchedules"
match="/DetailsResponse/ScheduleDetails/item"
use="concat(DocumentNumber,'-',ItemNumber)" />
<xsl:template match="/DetailsResponse">
<Response>
<Data>
<Items>
<xsl:apply-templates select="ItemDetails/item" />
</Items>
</Data>
</Response>
</xsl:template>
<xsl:template match="item">
<Item>
<LineNumber>
<Internal>
<xsl:value-of select="ItemNumber"/>
</Internal>
</LineNumber>
<ConfirmedQuantity>
<Value>
<xsl:value-of select="format-number(key('itemSchedules',
concat(DocumentNumber,'-',ItemNumber))/ConfirmedQuantity,0)" />
</Value>
</ConfirmedQuantity>
<Article>
<Number>
<xsl:value-of select="MaterialNumber"/>
</Number>
<Description>
<xsl:value-of select="Description"/>
</Description>
</Article>
</Item>
</xsl:template>
</xsl:stylesheet>
The xsl:key retains an index of references to the schedule details 'part' of the puzzle, and we create a catenated key of DocumentNumber and ItemNumber.
Recently we have upgraded to Tridion 2011 SP1 from Tridion 5.3.
In our existing implementation we have various Dynamic Component Templates. For few CTs output format is ASCX Web Control for few CTs output format is HTML Fragment.
After publishing we came across
1) ASCX WebControls are NOT stored to Storage Database (SQLServer). In Tridion 5.3 they were.
2) HTML Fragments are getting stored in database.
In our implementation binary files, page, embedded component templates are stored on file system and Dynamic component templates are stored in SQL Sever database.
We think we have missed something in our cd_storage_config. Please find attached config file.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration Version="6.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schemas/cd_storage_conf.xsd">
<Global>
<ObjectCache Enabled="false">
<Policy Type="LRU" Class="com.tridion.cache.LRUPolicy">
<Param Name="MemSize" Value="16mb"/>
</Policy>
<Features>
<Feature Type="DependencyTracker" Class="com.tridion.cache.DependencyTracker"/>
</Features>
</ObjectCache>
<Storages>
<Storage Type="persistence" Id="sqlserver" dialect="MSSQL" Class="com.tridion.storage.persistence.JPADAOFactory">
<Pool Type="jdbc" Size="5" MonitorInterval="60" IdleTimeout="120" CheckoutTimeout="120" />
<DataSource Class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
<Property Name="serverName" Value="local" />
<Property Name="portNumber" Value="1433" />
<Property Name="databaseName" Value="TridionBroker" />
<Property Name="user" Value="TridionBrokerUser" />
<Property Name="password" Value="mypass" />
</DataSource>
</Storage>
<Storage Type="filesystem" Class="com.tridion.storage.filesystem.FSDAOFactory" Id="defaultFile" defaultFilesystem="false">
<Root Path="d:\Inetpub\MyPortal" />
</Storage>
<Storage Type="filesystem" Class="com.tridion.storage.filesystem.FSDAOFactory" Id="defaultDataFile" defaultFilesystem="true" defaultStorage="true">
<Root Path="d:\Inetpub\MyPortal\data" />
</Storage>
<SearchFilter Name="SearchFilter" Class="com.tridion.broker.components.meta.MsSqlSearchFilterHome" defaultStorageId="sqlserver"/>
</Storages>
</Global>
<ItemTypes defaultStorageId="defaultDataFile" cached="false">
<Item typeMapping="Query" storageId="sqlserver"/>
<Item typeMapping="Page" cached="false" storageId="defaultFile"/>
<Item typeMapping="Binary" cached="false" storageId="defaultFile"/>
<Item typeMapping="ComponentPresentation" itemExtension=".Jsp" storageId="sqlserver"/>
<Item typeMapping="ComponentPresentation" itemExtension=".Asp" storageId="sqlserver"/>
<Item typeMapping="ComponentPresentation" itemExtension=".Xml" storageId="sqlserver"/>
<Item typeMapping="ComponentPresentation" itemExtension=".Txt" storageId="sqlserver"/>
<Item typeMapping="Metadata" cached="true" storageId="sqlserver"/>
<Item typeMapping="XSLT" cached="true" storageId="sqlserver"/>
</ItemTypes>
<License Location="d:\Tridion\config\cd_licenses.xml"/>
You don't have any ascx binding in your storage config. In 5.3, it used to be Asp binding.
Change the following:
<Item typeMapping="ComponentPresentation" itemExtension=".Asp" storageId="sqlserver"/>
To:
<Item typeMapping="ComponentPresentation" itemExtension=".ascx" storageId="sqlserver"/>
Also, in tridion 2011 you don't need to specify mapping for each type (like txt, jsp etc..) if you want all to be stored in db.
You can simply do this:
<Item typeMapping="ComponentPresentation" storageId="sqlserver"/>
Example:
<Item name="item1">
<mode = "ax, bx" />
</Item>
<Item name="item2">
<mode = "bx, cx" />
</Item>
<Item name="item3">
<mode = "cx, dx" />
</Item>
In the example above I would like to extract all the items with modes containing "cx".
Thanks in advance!
Your XML in the example is not well formed. Assuming you meant:
<Items>
<Item name="item1">
<mode>ax, bx</mode>
</Item>
<Item name="item2">
<mode>bx, cx</mode>
</Item>
<Item name="item3">
<mode>cx, dx</mode>
</Item>
</Items>
you can do:
var els=from el in XDocument.Parse(inxml).Descendants("Item")
where el.Element("mode").Value.Contains("bx")
select el;
That is not legal XML (mode is an element name, you can set it equal to a string), but you should be able to do something like this, assuming that the string you are matching is the element value:
doc.Descendants("Item").Where( item => item.Elements("mode").Any( mode => mode.Value.Contains("cx")));
Assuming a well formed XML doc:
<Items>
<Item name="item1">
<mode>ax, bx</mode>
</Item>
<Item name="item2">
<mode>bx, cx</mode>
</Item>
<Item name="item3">
<mode>cx, dx</mode>
</Item>
</Items>
Do something like this:
XElement items = XElement.Load(#"C:\items.xml");
var filteredItems = from item in items.Descendants("Item")
where item.Element("mode").Value.Contains("cx")
select item;
foreach (var item in filteredItems)
{
Console.WriteLine(item.FirstAttribute.Value);
}
Output:
item2
item3
We are using XSLT to display xml attributes depending upon their value. We are able to do it from server side using C#. But we are not getting how to achieve it through XSLT.
We are using sample xml as;
<BookInfo>
<BookTable show="Book 1" >
<book id="book1" value="Book 1" />
<book id="book2" value="Book 2" />
</BookTable>
</BookInfo>
We want to read "show" attribute value and depending upon the value, we want to display the node information.
Please help me to achieve this using XSLT.
Thanks in advance.
Modified xml;
<Book>
<Info>
<Item name="Item1" type="DropDown" defaultValue="Two" values="One,Two,Three" />
<Item name="One" type="Label" value="some text" />
<Item name="Two" type="TextBox" value="another text" />
<Item key="Three" name="CheckBox" value="true" />
</Info>
</Book>
Unfortunately the xml format got changed. Now, in this case, for Item1 defaultValue is two, so node with name "two" should be returned.
It's something like:
<xsl:template match="BookTable">
<xsl:value-of select="book[#value = current()/#show]"/>
</xsl:template>
EDIT
Your second example isn't quite clear, I'm assuming there is always a <Item name="Item1"> node, that points to the real node that should be displayed.
<xsl:template match="Info">
<xsl:copy-of select="Item[#name = Item[#name='Item1']/#defaultValue]" />
</xsl:template>
In the XPath you need a # to get at the value of an attribute of your input-xml.
The Item[#name = ...] selects an item where the value of the name attribute equals the specified value.
The current() gives access to the current node that the template is processing. You need that as a plain #show would select the value of that attribute for the node being selected. Example: an Item[#name = #defaultValue] would select Items where the values for 'name' and 'defaultValue' are identical.