我正在尝试解析具有以下(简化)结构的文档。每个文档可以有一个或多个ORB段,每个段后跟一个或多个OBX段。 OBX段直接与前面的OBR段相关。
<obr> ...... </obr>
<obx> ...... </obx>
<obx> ...... </obx>
<obx> ...... </obx>
<obr> ...... </obr>
<obx> ...... </obx>
<obx> ...... </obx>
以下是更详细但仍简化的示例:
<OBR>
<OBR.1>
<OBR.1.1>1</OBR.1.1>
</OBR.1>
<OBR.2/>
<OBR.3>
<OBR.3.1>12345678</OBR.3.1>
<OBR.3.2>PLS</OBR.3.2>
</OBR.3>
<OBR.4>
<OBR.4.1>CRP, LFT, Ue</OBR.4.1>
<OBR.4.2>C Reactive protein, Liver Function Tests, Urea, Elec, Creat</OBR.4.2>
<OBR.4.3>PLS</OBR.4.3>
</OBR.4>
</OBR>
<OBX>
<OBX.1>
<OBX.1.1>1</OBX.1.1>
</OBX.1>
<OBX.2>
<OBX.2.1>NM</OBX.2.1>
</OBX.2>
<OBX.3>
<OBX.3.1>CRP</OBX.3.1>
<OBX.3.2>C-Reactive Protein</OBX.3.2>
<OBX.3.3>PLS</OBX.3.3>
</OBX.3>
</OBX>
我需要开发xPath表达式/ Java代码,它可以从多个文本中提取特定OBR段的文本。可以直接使用以下方法在整个文档中提取索引'OBX.3.2
public Object read(String expression, QName returnType, int index) {
expression = "(" + expression + ")[" + Integer.toString(index) + "]";
try {
XPathExpression xPathExpression = xPath.compile(expression);
return xPathExpression.evaluate(xmlDocument, returnType);
} catch (XPathExpressionException ex) {
ex.printStackTrace();
return null;
}
}
但我不知道如何找到与第二个OBR相关的索引'OBX.3.2,或者确实如何计算每个OBR的OBX段数(如果我新建这个我可能解决问题)。任何指导或建议将不胜感激。
我也尝试过Kayessian方法($ ns1 [count(。| $ ns2)= count($ ns2)])来计算给出的元素:
count( //OBR[3]/following-sibling::OBX [ count (.|//OBR[4]/preceding-sibling::OBX) = count(//OBR[4]/preceding-sibling::OBX )])
此表达式给出了索引OBR和下一个OBR下面的OBX元素的数量。但是它没有正确处理组中的最后一个OBR(因为它之后没有ORB)
答案 0 :(得分:1)
我会使用XSLT将原始XML转换为更方便的形式并处理结果。
示例XSLT转换:
<?xml version="1.0" encoding="UTF-8"?>
<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:template match="OBR">
<xsl:variable name="$cur_OBR" select="."/>
<xsl:variable
name="obx"
select="following-sibling::OBX[preceding-sibling::OBR[1] = $cur_OBR]"/>
<OBR position="{position()}">
<xsl:for-each select="*/*">
<xsl:variable name="suffix"
select="substring-after(name(), 'OBR')"/>
<xsl:variable name="rel_obx"
select="$obx/*/*[ends-with(name(), $suffix)]"/>
<xsl:apply-templates select="." mode="sub_OBR">
<xsl:with-params name="suffix" select="$suffix"/>
<xsl:with-params name="rel_obx" select="$rel_obx"/>
</xsl:apply-templates>
</xsl:for-each>
</OBR>
</xsl:template>
<xsl:template match="OBX"/>
<xsl:template mode="sub_OBR" match="*">
<xsl:param name="suffix" select="substring-after(name(), 'OBR')"/>
<xsl:param name="rel_obx"/>
<xsl:element name="concat('OBR', $suffix)">
<OBR>
<xsl:apply-templates select="text()"/>
</OBR>
<xsl:for-each select="$rel_obx">
<OBX>
<xsl:apply-templates select="text()"/>
</OBX>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我没有运行它来检查它是否绝对正确。您还可以看到,您需要一个变量来为具有xpath的OBR选择相应的OBX元素:following-sibling::OBX[preceding-sibling::OBR[1] = $cur_OBR]
。
答案 1 :(得分:0)
如果其他人偶然发现:计算细分的解决方案非常简单:
在第i个OBR之后计算OBX:
count(//OBR[i]/following-sibling::OBX) - count(//OBR[i+1]/following-sibling::OBX)
然后可以使用上面的阅读器代码循环遍历相应的片段。