I fail stripping whitespaces inside of inline elements in FOP with DITA-OT PDF2. This is my code snippet:
<p>1 BEFORE <uicontrol>test</uicontrol> AFTER</p>
<p>2 BEFORE <uicontrol> test</uicontrol> AFTER</p>
<p>3 BEFORE <uicontrol>test </uicontrol> AFTER</p>
<p>4 BEFORE <uicontrol><keyword keyref="test"/> </uicontrol> AFTER</p>
<p>5 BEFORE <uicontrol> <keyword keyref="test"/></uicontrol> AFTER</p>
<p>6 BEFORE <uicontrol>
<keyword keyref="test"/>
</uicontrol> AFTER</p>
<p>7 BEFORE <uicontrol>
<keyword keyref="test"/>
</uicontrol> AFTER</p>
Renders to:
This is my attribute set:
<xsl:attribute-set name="uicontrol">
<xsl:attribute name="white-space">nowrap</xsl:attribute>
<xsl:attribute name="white-space-treatment">ignore</xsl:attribute>
<xsl:attribute name="white-space-collapse">true</xsl:attribute>
<xsl:attribute name="linefeed-treatment">treat-as-zero-width-space</xsl:attribute>
<xsl:attribute name="background-color">#ff0000</xsl:attribute>
</xsl:attribute-set>
All red whitespaces have to be stripped. Where is my mistake?
FOP seems to have difficulty in "white-space-treatment":
XSL-FO Property Support Table (ยง7)
So it may be needed to use <xsl:strip-space elements="uicontrol"> plus normalize-space() function for text() in uicontrol.
Following is the result when specifying <xsl:strip-space elements="uicontrol">
For your reference, Antenna House renders your original style definition as follows:
Hope this helps your development.
Related
I have a test xml and I want to get the value from this line ATTRIBUTE NAME="News- offers_OPT_EMAIL">F
so I can check for the value F or T
if I do below I can get the title but how do I get the above line value.
[xml]$xml = Get-Content testFile.xml
$xml
$xml.CUSTOMERS.CUSTOMER.NAME.TITLE
sample XML code
<?xml version="1.0" encoding="UTF-8"?>
<CUSTOMERS xml:lang="en">
<CUSTOMER CREATED_DATE="2018-01-01 05:18:53.0" GROUP_ID="" ID="95656565">
<NAME>
<TITLE>M</TITLE>
<FIRST_NAME>Joe</FIRST_NAME>
<LAST_NAME>Smith</LAST_NAME>
</NAME>
<GENDER/>
<DATE_OF_BIRTH/>
<ADDRESS>
<ADDRESS_LINE_1>1 White House</ADDRESS_LINE_1>
<ADDRESS_LINE_2>Old Ave</ADDRESS_LINE_2>
<ADDRESS_LINE_3/>
<TOWNCITY>LONDON</TOWNCITY>
<COUNTY/>
<POSTCODE>18659</POSTCODE>
<COUNTRY>France</COUNTRY>
</ADDRESS>
<ADDRESS>
<ADDRESS_LINE_1>175 avenue de la division Leclerc</ADDRESS_LINE_1>
<ADDRESS_LINE_2/>
<ADDRESS_LINE_3/>
<TOWNCITY>Antony</TOWNCITY>
<COUNTY/>
<POSTCODE>92160</POSTCODE>
<COUNTRY>France</COUNTRY>
</ADDRESS>
<CONTACT_DETAILS>
<TELEPHONE MARKETING_OPT_IN="F" TYPE="MOBILE">0123456789</TELEPHONE>
<EMAIL MARKETING_OPT_IN="F">johnsmith#gmail.com</EMAIL>
</CONTACT_DETAILS>
<ATTRIBUTE NAME="News- offers_OPT_EMAIL">F</ATTRIBUTE>
<NOTE>NA</NOTE>
</CUSTOMER>
You could use SelectSingleNode or SelectNodes with an XPath expression. There are several options to achieve what you want, depending on your intention, but this would be one way to do it:
# finde the nodes
$nodes = $xml.SelectNodes("//*[local-name()='ATTRIBUTE'][#NAME='News- offers_OPT_EMAIL']")
# get value
$nodes.InnerText
Or if the value of the attribute doesn't matter, simply do:
$xml.customers.customer.attribute.'#text'
Having followed the example found earlier here on StackOverflow (dateSignedTabs does not work), I still fail to get a signature date to appear. Here's a snippet of the xml.
<?xml version="1.0" encoding="UTF-8"?>
<envelopeDefinition xmlns="http://www.docusign.com/restapi">
<emailSubject>Boiler Contract -00006)</emailSubject>
<status>sent</status>
<documents>
<document>
<documentId>1</documentId>
<name>VDBK SW6-CSIK-0001.pdf</name>
</document>
</documents>
<recipients>
<signers>
<signer>
<recipientId>1</recipientId>
<routingOrder>1</routingOrder>
<note>Team</note>
<email>joebloggs#gmail.com</email>
<name>Eric Test6-1</name>
<tabs>
<signHereTabs>
<signHere>
<xPosition>58</xPosition>
<yPosition>617</yPosition>
<documentId>1</documentId>
<pageNumber>1</pageNumber>
</signHere>
</signHereTabs>
<dateSignedTabs>
<dateSigned>
<xPosition>58</xPosition>
<yPosition>440</yPosition>
<tabLabel>Date Signed</tabLabel>
<name>Date Signed</name>
<documentId>1</documentId>
<pageNumber>1</pageNumber>
<recipientId>1</recipientId>
</dateSigned>
</dateSignedTabs>
</tabs>
</signer>
</signers>
</recipients>
</envelopeDefinition>
Can anybody spot why this is off?
I'm making my own component, and I want to have oportunity to set some properties in form builder. In all I want to reach effect similar to autocomplete control, where I can set 3 properties (URI, xpath, and relative xpath). I read, that I can do it using control-details markup, but unfortunately it does not work. This is code (I working on davinci tutorial):
<xbl:binding element="fr|tutorial-davinci" id="fr-tutorial-davinci" xxbl:mode="lhha binding value">
<metadata xmlns="http://orbeon.org/oxf/xml/form-builder" xmlns:xf="http://www.w3.org/2002/xforms">
<display-name lang="en">davinci-modified</display-name>
<templates>
<instance label=""/>
<view>
<fr:tutorial-davinci id="" appearance="minimal" labelref="#label" xmlns="" resource="" >
<xf:label ref=""/>
<xf:hint ref=""/>
<xf:help ref=""/>
<xf:alert ref=""/>
</fr:tutorial-davinci>
</view>
</templates>
<control-details>
<xf:input>
<xf:label lang="en">Some param</xf:label>
</xf:input>
</control-details>
</metadata>
<xbl:template>
<xf:model>
<xf:instance id="id1"><value/></xf:instance>
</xf:model>
<xf:input ref="instance('id1')" />
</xbl:template>
</xbl:binding>
You must have a ref attribute on<xf:input> which points to an attribute or element where the information will be stored. In autocomplete.xml, there is in particular theresource` attribute, which:
is pointed to by <xf:input>
is present on the <fr:autocomplete> template
How do I access following XML file using xmlparsing on an iphone?
<?xml version="1.0" encoding="iso-8859-1"?>
<chapter>
<TITLE>Title &plainEntity;</TITLE>
<para>
<informaltable>
<tgroup cols="3">
<tbody>
<row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
<row><entry>a2<<?xml version="1.0" encoding="iso-8859-1"?>
<ADDRESS>
<CONTACT>
<NAME FIRST="Fred" LAST="Bloggs" NICK="Bloggsie" TITLE="Mr" />
<STREET HOME="5 Any Street" WORK="Floor 24, BigShot Tower" />
<CITY HOME="Little Town" WORK="Anycity" />
<COUNTY HOME="Anyshire" WORK="Anyshire" />
<POSTAL HOME="as plain text" WORK="text" />
<COUNTRY HOME="UK" WORK="UK" />
<PHONE HOME="as text" WORK="text" />
<FAX HOME="none" WORK="555" />
<MOBILE HOME="444" WORK="333" />
<WEB HOME="www.codehelp.co.uk" WORK="" />
<COMPANY>Full name of company here</COMPANY>
<GENDER>male</GENDER>
<BDAY>Add tags for year, month and day to make this more useful</BDAY>
<ANNI>some date long forgotten :-)</ANNI>
<SPOUSE>angry</SPOUSE>
<CHILDREN>Make sure this tag is one of the ones allowed to repeat in the DTD</CHILDREN>
<COMMENT>comments here</COMMENT>
<EMAILONE>Either use fixed tags like this, or change to a repeating tag</EMAILONE>
<EMAILTWO>second email line</EMAILTWO>
<EMAILTHREE>third</EMAILTHREE>
<EMAILFOUR>fourth</EMAILFOUR>
</CONTACT>
</ADDRESS>/entry><entry>c2</entry></row>
<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
&systemEntity;
<section id="about">
<title>About this Document</title>
<para>
<!-- this is a comment -->
</para>
</section>
</chapter>
The SDK provides two ways to parse XML: libxml2 and NSXMLParser. libxml2 is the fastest. To use it in your project, go to the build settings for your iPhone App project and set the following:
Other linker flags = -lxml2
Header Search Paths: $(SDKROOT)/usr/include/libxml2
Then download XPathQuery.m and XPathQuery.h from this page: Using libxml2 for XML parsing and XPath queries in Cocoa, which also provides a tutorial on how to use it. That XPathQuery class is a simplified way to parse XML. I recommend it unless you want to write the same code yourself, which doesn't seem the case.
With that on place, do
NSString *string = nil; // put your html document here
NSData *htmlData = [string dataUsingEncoding:NSUTF8StringEncoding];
NSString *xpath = #"//row"; // any standard XPath expression
NSArray *nodesArray = PerformHTMLXPathQuery(htmlData, xpath);
NSDictionary *dict;
if (0<[nodesArray count]) {
dict = [nodesArray objectAtIndex:0];
}
At this point the elements from your document should be inside the dict dictionary.
Here are releated the SO post,
Parser XML with NSXMLParser
http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project
NSXMLParser example
below is the blog tutorial for using NSXMLParser.
http://markstruzinski.com/?p=47
i create a xml document with JAXP and search a way to insert the schemalocation.
At the moment my application produces:
<?xml version="1.0" encoding="UTF-8"?>
<root>
...
</root>
But i need:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="namespaceURL"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="namespaceURL pathToMySchema.xsd">
...
</root>
My code:
StreamResult result = new StreamResult(writer);
Document doc = getDocument();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.INDENT, "yes");
trans.setOutputProperty(OutputKeys.METHOD, "xml");
trans.setOutputProperty(OutputKeys.VERSION, "1.0");
trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
DOMSource source = new DOMSource(depl.getAsElement(doc));
trans.transform(source, result);
Thanks for your time,
Kasten
In XML data model namespace nodes are not actually read from parent element but each element has its own namespace nodes. Therefore simply adding a new default namespace to root element doesn't work but results in a document like this
<root xmlns="namespaceURL">
<child xmlns=""/>
...
</root>
Notice the appearing of empty default namespace xmlns="" on the child element(s). What actually needs to be done is to modify the namespace of every node or to create a new document with the desired default namespace and copy the contents, element and attribute names etc. of the old document to the new one. These can be done by recursively going through the original document. With Java DOM implementation this can be laborious, I've heard. One short cut might be to read the document with a namespace-unaware DOM and then add as attribute the new default namespace. Other solution is to change the namespace with an XSLT transformation, which seems quite suitable in this case, since you actually are already generating the output via XSLT transformation.
Use this XSLT stylesheet to add a new default namespace and the schema location to the root element. This stylesheet preserves old namespaces but adds all elements to new default namespace if they previously were in no-namespace.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<!-- Template to add a default namespace to a document -->
<!-- Elements without a namespace are "moved" to default namespace -->
<!-- Elements with a namespace are copied as such -->
<!-- string for default namespace uri and schema location -->
<xsl:variable name="ns" select="'namespaceURL'"/>
<xsl:variable name="schemaLoc" select="'namespaceURL pathToMySchema.xsd'"/>
<!-- template for root element -->
<!-- adds default namespace and schema location -->
<xsl:template match="/*" priority="1">
<xsl:element name="{local-name()}" namespace="{$ns}">
<xsl:attribute name="xsi:schemaLocation"
namespace="http://www.w3.org/2001/XMLSchema-instance">
<xsl:value-of select="$schemaLoc"/>
</xsl:attribute>
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
<!--template for elements without a namespace -->
<xsl:template match="*[namespace-uri() = '']">
<xsl:element name="{local-name()}" namespace="{$ns}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
<!--template for elements with a namespace -->
<xsl:template match="*[not(namespace-uri() = '')]">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!--template to copy attributes, text, PIs and comments -->
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Instead of creating the transformer with
Transformer trans = transfac.newTransformer();
(which creates and stylesheet that does an identy transformation), create an XSLT input source and give it as a parameter to newTransformer()
javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource(xsltFile);
Transformer trans = transFact.newTransformer(xsltSource);
where xsltFile is a File object pointing to that XSLT file.
Set the output properties as you wish and call transform() as in your sample code. The result should be what you desired, but I have not tested this in Java. The given XSLT file is tested for some trivial cases and there is a sample input and output at the end of this answer.
Some minor notes:
The original document object is not modified in this process. The new default namespace only appears in the output of the transform() method.
The namespace prefix for schema-instance namespace is usually xsi:, not xs: as in your example code (xs: is used in schema definitions (as well as xsd:)) .
Sample input and output for the XSLT stylesheet shown above
Input:
<root>
<child>text</child>
<child attribute="attr-value"/>
<?pi-target pi-content?>
<nsx:ns-child xmlns:nsx="ns1x">
<no-ns-child>text</no-ns-child>
<!-- comment -->
<nsx:ns-child nsx:ns-attribute="nsx-attr-value">text</nsx:ns-child>
</nsx:ns-child>
<defns-child xmlns="default-ns">
<def-child attr="val">text</def-child>
<child xmlns=""/>
</defns-child>
<child>text</child>
</root>
Output:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="namespaceURL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="namespaceURL pathToMySchema.xsd">
<child>text</child>
<child attribute="attr-value"/>
<?pi-target pi-content?>
<nsx:ns-child xmlns:nsx="ns1x">
<no-ns-child>text</no-ns-child>
<!-- comment -->
<nsx:ns-child nsx:ns-attribute="nsx-attr-value">text</nsx:ns-child>
</nsx:ns-child>
<defns-child xmlns="default-ns">
<def-child attr="val">text</def-child>
<child xmlns="namespaceURL"/>
</defns-child>
<child>text</child>
</root>
You can add the namespaces in the root when creating the document.
String NS_URL = "namespaceURL";
doc = builder.newDocument();
Element root = doc.createElementNS(NS_URL, "root");
root.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance",
"xs:schemaLocation", NS_URL + " pathToMySchema.xsd");
doc.appendChild(root);
Then for each element added to the doc instead of createElement() use createElementNS()
doc.createElementNS(NS_URL, name);
This results in what you were looking for.
<root
xmlns="namespaceURL"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="namespaceURL pathToMySchema.xsd"
>
Here's how to give a hint to the parser in order to solve your problem:
http://bytes.com/topic/java/answers/16892-xerces-how-perfrom-schema-validations-without-using-xsi-schemalocation
It goes like this:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(true);
dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLocation",
"http://www.example.com/Report.xsd");
Here is a validation example with some source code. It might help you.
http://www.ibm.com/developerworks/xml/library/x-tipvalschm/
(If all comes to worse, you can always search-and-replace. I know it is not the ideal solution, but the javax.xml.transform.OutputKeys doesn't seem to have a member related to the schemalocation attribute.)