Я создал следующий код для простого флажка в таблице, используя XSL-FO:
Java-код
Element svg = document.createElement("svg");
svg.setAttribute("width", "12pt");
svg.setAttribute("height", "12pt");
svg.setAttribute("viewBox", "0 0 24 24");
Element rect = document.createElement("rect");
rect.setAttribute("x", "2");
rect.setAttribute("y", "2");
rect.setAttribute("width", "20");
rect.setAttribute("height", "20");
rect.setAttribute("fill", "none");
rect.setAttribute("stroke", "black");
svg.appendChild(rect);
<fo:table-cell border = "solid 1px black" font-family = "Arial" font-size = "12pt" padding = "2pt">
<fo:block>
<fo:inline>Checkbox: </fo:inline>
<fo:inline>
<fo:instream-foreign-object>
<svg height = "12pt" viewBox = "0 0 24 24" width = "12pt">
<rect fill = "none" height = "20" stroke = "black" width = "20" x = "2" y = "2"/>
</svg>
</fo:instream-foreign-object>
</fo:inline>
</fo:block>
</fo:table-cell>
Однако когда я пытаюсь преобразовать его в PDF, я получаю следующее предупреждение: Unknown formatting object "{}svg" encountered (a child of fo:instream-foreign-object}
Что может быть причиной этой ошибки?
Я попробовал добавить свойства SVG в конфигурацию FOP и использовать тег fo:svg, но это все равно не работает должным образом.
@RobertLongson попробую, спасибо
Вы объявили пространство имен SVG в документе FO? Из фрагмента видно, что пространство имен SVG является основным пространством имен, но если это указано как svg:xmlns = "..."
, все элементы в пространстве имен SVG должны иметь svg:...
перед именем элемента. Или создано с помощью createElementNS, как упоминает @RobertLongson.
Спасибо, @chrwahl, за идею с xmlns
. Что касается svg:...
, то у них не должно быть svg:...
, это лишнее. Я исправил это, просто добавив xmlns = "http://www.w3.org/2000/svg"
.
FOP должен знать тип XML, который вы ему передаете. В этом случае задействованы два пространства имен XML; Объекты форматирования http://www.w3.org/1999/XSL/Format
и SVG http://www.w3.org/2000/svg
.
Существуют разные способы объявления пространства имен. И вы можете увидеть их в этом примере PDF. В следующем примере пространство имен SVG просто объявляется в элементе svg, а затем FOP знает, что все дочерние элементы принадлежат к одному и тому же пространству имен (если не объявлено другое пространство имен).
<?xml version = "1.0" encoding = "UTF-8"?>
<root xmlns = "http://www.w3.org/1999/XSL/Format">
<layout-master-set>
<simple-page-master margin = "10mm" page-width = "210mm" page-height = "297mm" master-name = "simple">
<region-body region-name = "simple-body" margin-bottom = "20mm" margin-top = "20mm" />
</simple-page-master>
</layout-master-set>
<page-sequence master-reference = "simple">
<flow flow-name = "simple-body">
<block>Hello World!</block>
<block>
<instream-foreign-object>
<svg xmlns = "http://www.w3.org/2000/svg" height = "12pt" viewBox = "0 0 24 24" width = "12pt">
<rect fill = "none" height = "20" stroke = "black" width = "20" x = "2" y = "2"/>
</svg>
</instream-foreign-object>
</block>
</flow>
</page-sequence>
</root>
В Java, вероятно, будет нормально, если вы просто используете createElementNS с пространством имен SVG, и Java узнает, как объявить пространство имен SVG в XML-документе.
В качестве примера XSL-FO вы добавляете в смесь пространство имен XSL http://www.w3.org/1999/XSL/Transform
, позволяя либо XSL, либо пространству имен FO быть основным. В этом случае я думаю, что имеет смысл использовать FO в качестве основного, поскольку результатом преобразования XSL является документ FO (со встроенным в него некоторым количеством SVG).
<?xml version = "1.0"?>
<xsl:stylesheet version = "1.0"
xmlns = "http://www.w3.org/1999/XSL/Format"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:svg = "http://www.w3.org/2000/svg">
<xsl:template match = "/">
<root>
<layout-master-set>
<simple-page-master margin = "10mm" page-width = "210mm" page-height = "297mm" master-name = "simple">
<region-body region-name = "simple-body" margin-bottom = "20mm" margin-top = "20mm" />
</simple-page-master>
</layout-master-set>
<page-sequence master-reference = "simple">
<flow flow-name = "simple-body">
<block>Hello World!</block>
<block>
<instream-foreign-object>
<svg:svg height = "12pt" viewBox = "0 0 24 24" width = "12pt">
<svg:rect fill = "none" height = "20" stroke = "black" width = "20" x = "2" y = "2"/>
</svg:svg>
</instream-foreign-object>
</block>
</flow>
</page-sequence>
</root>
</xsl:template>
</xsl:stylesheet>
Спасибо @chrwahl
Исправили это, просто добавив xmlns="http://www.w3.org/2000/svg". Этого было достаточно.
Element svg = document.createElement("svg");
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
svg.setAttribute("width", "12pt");
svg.setAttribute("height", "12pt");
svg.setAttribute("viewBox", "0 0 24 24");
Вы уверены, что вам не следует использовать createElementNS вместо createElement?