我的任务是将Text和任何相关的Font Attributes从以下(简化的)示例XML中剥离到FileMaker数据库中。示例XML:
<Font Id="Arial" Script="normal" Size="32" Underlined="no" Italic="no" Weight="normal">
<Paragraph>
<Text>This <Font Italic="yes">word</Font> is italic</Text>
<Text>This entire line has no formatting</Text>
<Text>This<Font Italic="yes">line</Font><Font Underlined="yes" Italic = "yes"> has multiple formats</Font></Text>
</Paragraph>
<Paragraph>
<Text>This is the first line of the second paragraph and has no formatting</Text>
<Text>This line also has no formatting</Text>
<Text><Font Underlined="yes">This entire line is underlined</Font></Text>
</Paragraph>
</Font>
如您所见,<Paragraph>
元素由`节点包围。 (我希望我正确地指这些部分)。我已成功编写代码,以便在存在NO嵌套Font属性时将单个FULL行文本与嵌套Font属性一起传输到数据库中,或者嵌套Font属性包含整个文本数据。
我所坚持的是如何处理在文本数据中嵌套属性的文本行,例如第一段中的第一行和第一段中的第三行。
我要做的是捕获每个数据片段及其属性。我的架构允许每行文本(a,b,c)最多三个嵌套的Font属性。使用示例XML文件,我的FileMaker数据库对于段落1应该如此(简化):
Record 1 Line 1a Text: This Line 1a Italic: (no value) Line 1a Underlined: (no value) Line 1b Text: word Line 1b Italic: yes Line 1b Underlined: (no value) Line 1c Text: is italic Line 1c Italic: (no value) Line 1c Underlined: (no value) Line 2a Text: This entire line has no formatting Line 2a Italic: (no value) Line 2a Underlined: (no value) Line 2b Text: (no value) Line 2b Italic: (no value) Line 2b Underlined: (no value) Line 2c Text: (no value) Line 2c Italic: (no value) Line 2c Underlined: (no value) Line 3a Text: This Line 3a Italic: (no value) Line 3a Underlined: (no value) Line 3b Text: line Line 3b Italic: yes Line 3b Underlined: (no value) Line 3c Text: has multiple formats Line 3c Italic: yes Line 3c Underlined: yes
当然,我无法预测何时何地应用格式。我希望我已经清楚了,并且事先感谢你提供的任何指示,以帮助我完成这项任务。
答案 0 :(得分:1)
我建议你尝试这样的事情,至少作为你的出发点:
<强> XSLT 强>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/Font">
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
<METADATA>
<FIELD NAME="Text"/>
<FIELD NAME="IsItalic" TYPE="NUMBER"/>
<FIELD NAME="IsUnderline" TYPE="TEXT"/>
<FIELD NAME="Paragraph" TYPE="TEXT"/>
</METADATA>
<RESULTSET>
<!-- create a record for each text node, descendant of Paragraph -->
<xsl:for-each select="Paragraph//text()">
<ROW>
<!-- get the value of the current text node itself -->
<COL><DATA><xsl:value-of select="."/></DATA></COL>
<!-- get the value of @Italic from the nearest ancestor that has such attribute -->
<COL><DATA><xsl:value-of select="ancestor::*[@Italic][1]/@Italic"/></DATA></COL>
<!-- get the value of @Underlined from the nearest ancestor that has such attribute -->
<COL><DATA><xsl:value-of select="ancestor::*[@Underlined][1]/@Underlined"/></DATA></COL>
<!-- get the ID of the ancestor Paragraph -->
<COL><DATA><xsl:value-of select="generate-id(ancestor::Paragraph)"/></DATA></COL>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,您将获得:
请注意,段落ID仅在当前转换的范围内是唯一的,而不是普遍的。
根据我更好的判断,这是一个样式表,它将为每个Paragraph
创建一个记录,每个记录是3行3个文本节点的严格网格。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.filemaker.com/fmpxmlresult">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/Font">
<FMPXMLRESULT>
<METADATA>
<FIELD NAME="Line 1a Text"/>
<FIELD NAME="Line 1a Italic"/>
<FIELD NAME="Line 1a Underlined"/>
<FIELD NAME="Line 1b Text"/>
<FIELD NAME="Line 1b Italic"/>
<FIELD NAME="Line 1b Underlined"/>
<FIELD NAME="Line 1c Text"/>
<FIELD NAME="Line 1c Italic"/>
<FIELD NAME="Line 1c Underlined"/>
<FIELD NAME="Line 2a Text"/>
<FIELD NAME="Line 2a Italic"/>
<FIELD NAME="Line 2a Underlined"/>
<FIELD NAME="Line 2b Text"/>
<FIELD NAME="Line 2b Italic"/>
<FIELD NAME="Line 2b Underlined"/>
<FIELD NAME="Line 2c Text"/>
<FIELD NAME="Line 2c Italic"/>
<FIELD NAME="Line 2c Underlined"/>
<FIELD NAME="Line 3a Text"/>
<FIELD NAME="Line 3a Italic"/>
<FIELD NAME="Line 3a Underlined"/>
<FIELD NAME="Line 3b Text"/>
<FIELD NAME="Line 3b Italic"/>
<FIELD NAME="Line 3b Underlined"/>
<FIELD NAME="Line 3c Text"/>
<FIELD NAME="Line 3c Italic"/>
<FIELD NAME="Line 3c Underlined"/>
</METADATA>
<RESULTSET>
<!-- create a record for each Paragraph -->
<xsl:for-each select="Paragraph">
<ROW>
<!-- for each line ... -->
<xsl:for-each select="Text">
<xsl:variable name="text-nodes" select=".//text()" />
<!-- process the first three text nodes -->
<xsl:call-template name="create-cells">
<xsl:with-param name="text-node" select="$text-nodes[1]"/>
</xsl:call-template>
<xsl:call-template name="create-cells">
<xsl:with-param name="text-node" select="$text-nodes[2]"/>
</xsl:call-template>
<xsl:call-template name="create-cells">
<xsl:with-param name="text-node" select="$text-nodes[3]"/>
</xsl:call-template>
</xsl:for-each>
</ROW>
</xsl:for-each>
</RESULTSET>
</FMPXMLRESULT>
</xsl:template>
<xsl:template name="create-cells">
<xsl:param name="text-node"/>
<!-- get the value of the text node itself -->
<COL><DATA><xsl:value-of select="$text-node"/></DATA></COL>
<!-- get the value of @Italic from the nearest ancestor that has such attribute -->
<COL><DATA><xsl:value-of select="$text-node/ancestor::*[@Italic][1]/@Italic"/></DATA></COL>
<!-- get the value of @Underlined from the nearest ancestor that has such attribute -->
<COL><DATA><xsl:value-of select="$text-node/ancestor::*[@Underlined][1]/@Underlined"/></DATA></COL>
</xsl:template>
</xsl:stylesheet>
结果看起来像这样(列表视图中显示两条记录):