Resolving Cross References

Oxygen general issues.
xmlman
Posts: 13
Joined: Wed Oct 12, 2011 7:51 pm

Resolving Cross References

Post by xmlman »

I could use some help building a CSS for a custom DTD.

Each file has a number of figures. The figures are numbered continuously from the beginning of the XML instance to the end. I have created a counter for the figures. Also, each figure element has a populated id attribute.

figure {
counter-increment: figure;
display: block;
}
figure>title:before {
font-size: 10pt;
font-weight: bold;
display: inline;
content: "Figure " counter(figure)". ";
}

Within the paragraphs of the XML is an element that references those figures. The element is <callout>. The callout element has two attributes, "assocfig" and "label". "assocfig" is an IDREF attribute that references one of the figures within that XML file. In Author I need to display for the callout element:

Figure 1, Item 1

the value for Item comes from the "label" attribute. How do resolve the value of "assocfig" to create number that corresponds to the counter generated number for whichever figure is referenced by "assocfig."?

The <figure> referenced by "assocfig" could either precede or follow the <callout> element.
mihaela
Posts: 490
Joined: Wed May 20, 2009 2:40 pm

Re: Resolving Cross References

Post by mihaela »

Hello,

You can use an XPath expression in the CSS for the callout element, to evaluate the index of the figure that has the same id with its assocfig attribute value, something like:

Code: Select all


callout{
content:oxy_concat(
" Figure ",
oxy_xpath(oxy_concat(
"index-of(//figure/@id, \"",
attr("assocfig"),
"\")[1]")),
", Item ",
attr("label"));
}
The drawback of this approach is that when you use XPath expressions in your CSS, they must be reevaluated on each modification of the document. That may lead to a slowdown on editing (big documents) in Author mode.

Another possibility is to use Author SDK to create an implementation of a ro.sync.ecss.extensions.api.StylesFilter that imposes the desired content for callout elements.
Here is the online documentation about the configuration of an ExtensionsBundle:
http://www.oxygenxml.com/doc/ug-editor/ ... undle.html

To provide a custom StylesFilter in your ExtensionsBundle, you must implement the following method:

Code: Select all


  public StylesFilter createAuthorStylesFilter() {
return new CustomStylesFilter();
}
Here is a possible implementation of the CustomStylesFilter:

Code: Select all


public class CustomStylesFilter implements StylesFilter {

public Styles filter(Styles styles, AuthorNode authorNode) {
String figureID = null;
String itemID = "";
if ("callout".equals(authorNode.getName())) {
if (authorNode instanceof AuthorElement) {
// Get the id of the associated figure
AttrValue assocfig = ((AuthorElement) authorNode).getAttribute("assocfig");
if (assocfig != null) {
figureID = assocfig.getValue();
}
// Get the item value
AttrValue labelValue = ((AuthorElement) authorNode).getAttribute("label");
if (labelValue != null) {
itemID = labelValue.getValue();
}
}
}

if (figureID != null) {
AuthorDocument ownerDocument = authorNode.getOwnerDocument();
// Found the figure index
SearchFigureResult result = getFigureIndex(figureID, ownerDocument.getRootElement(), 0);
if (result != null && result.foundFigure) {
// Set the content for the current "callout" element
styles.setProperty(Styles.KEY_MIXED_CONTENT,
new StaticContent[] {
new StringContent("Figure " + result.figureCount + ", Item " + itemID)
});
}
}

return styles;
}


private SearchFigureResult getFigureIndex(String figureID, AuthorElement curentElement, int figureCount) {
SearchFigureResult result = new SearchFigureResult();
if ("figure".equals(curentElement.getName())) {
result.figureCount = figureCount + 1;
AttrValue idValue = curentElement.getAttribute("id");
if (idValue != null) {
String id = idValue.getValue();
if (figureID.equals(id)) {
// We found the figure
result.foundFigure = true;
}
}
}

if (!result.foundFigure) {
// Search the figure in current elements children
List<AuthorNode> contentNodes = curentElement.getContentNodes();
for (AuthorNode node : contentNodes) {
if (node instanceof AuthorElement) {
result = getFigureIndex(figureID, (AuthorElement) node, result.figureCount);
if (result.foundFigure) {
break;
}
}
}
}
return result;
}

private class SearchFigureResult {
int figureCount;
boolean foundFigure;
}

public String getDescription() {
return "Custom styles filter";
}
}
Best regards,
Mihaela
Mihaela Calotescu
http://www.oxygenxml.com
xmlman
Posts: 13
Joined: Wed Oct 12, 2011 7:51 pm

Re: Resolving Cross References

Post by xmlman »

I understand the xpath for getting the index for the corresponding figure, but it doesn't work. So far, I have not been able to get any xpath functions to work using oxy_xpath in my CSS.

I don't know the first thing about Java programming. So the xpath method works better for my understanding. However it seems the way the code is written, the value of the attribute "assocfig" is not being evaluated by "index-of(//figure/@id). Thus I'm not getting any number for "FIGURE".

Can you explain the \"" that falls between "index-of(//figure@id" and attr("assocfig"). Also the explain the backslash at the end of the expression. Additionally, why are the values in attr() quoted?
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Resolving Cross References

Post by Radu »

Hi Charles,

If oxy_xpath is not working for you maybe you are using an Oxygen version prior to version 13. If this is the case, please use xpath instead, it is the same function but we deprecated the old name in Oxygen 13 and added the oxy_ prefix to it.

Mihaela suggested you a workaround which used both the oxy_xpath function and CSS functions for obtaining the attribute value.
The equivalent using only xpath expressions is like this:

Code: Select all

callout{
content:" Figure " oxy_xpath("index-of(//*:figure/@id, @*:assocfig)[1]") ", Item " attr(label);
}
I used * in order to make the xpath expression work in case you might have the XML element or attribute name defined in some namespace.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
xmlman
Posts: 13
Joined: Wed Oct 12, 2011 7:51 pm

Re: Resolving Cross References

Post by xmlman »

I'm using Oxygen 13.1, build 2011102511.
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Resolving Cross References

Post by Radu »

Hi Charles,

So I understand that the oxy_xpath does not work at all for you.

Let's take this simple case.
XML file "test.xml":

Code: Select all

<?xml-stylesheet type="text/css" href="test.css"?>
<root>
<callout assocfig="testFig" label="TEST"/>
<figure id="fig1"/>
<figure id="fig2"/>
<figure id="testFig"/>
<figure id="fig4"/>
</root>
CSS file "test.css", in the same folder:

Code: Select all

callout{
content:oxy_xpath("local-name()");
}
When switching the XML to the Author page, is the local name of "callout" rendered in the Author for each "callout"?

If so, let's make the test.css more complicated like:

Code: Select all

*{
display:block;
}
callout{
content:" Figure " oxy_xpath("index-of(//figure/@id, @assocfig)") ", Item " attr(label);
}

figure{
content:oxy_xpath("@id");
}
Does the static text for the "callout" properly contain the figure index?

If so, maybe you could give me some sample XML code from your files (you could use our usual support@oxygenxml.com email address), do you have a namespace defined for your XML elements?

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
xmlman
Posts: 13
Joined: Wed Oct 12, 2011 7:51 pm

Re: Resolving Cross References

Post by xmlman »

Radu,

Works in the test file. Exact same code does not work in for own XML. We use no namespaces, other than the xlink namespace for one attribute.

I will have to create an XML instance with the current structure but with DUMMY content. I cannot, by US law, send you our content.

I really need to get this working because once this comes together, I can use similar code for generating numerals for Step, Figure and Table cross references.

I will email you an xml instance. I will use "Resolving Cross References" for the subject line.
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Resolving Cross References

Post by Radu »

Updating this thread with the findings.
The oxy_xpath extension CSS function did not properly work when the XML document contained referenced entities.
A fix for this will be available in Oxygen 13.2 (in January next year).

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply