英文:
How to get the ancestor node from this XML document?
问题
//Getting the column from the colors for all the columns
public static Map<String, List<String>> getColors(Document doc) {
String expressionGroupedCol = "/DynamicReport/Columns/Column/FormattingInfo/Header/FontInfo";
XPath xPath = XPathFactory.newInstance().newXPath();
Map<String, List<String>> colorMap = new HashMap<>();
try {
NodeList nodeList = (NodeList) xPath.compile(expressionGroupedCol).evaluate(
doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node nNode = nodeList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
String strTextColor = eElement.getElementsByTagName("TextColor").item(0).getTextContent();
String strBackgroundColor = eElement.getElementsByTagName("BackgroundColor").item(0).getTextContent();
// Traverse back to get the ColumnName
Node columnNode = nNode.getParentNode().getParentNode();
if (columnNode.getNodeType() == Node.ELEMENT_NODE) {
Element columnElement = (Element) columnNode;
String columnName = columnElement.getElementsByTagName("ColumnName").item(0).getTextContent();
// Add to the map
colorMap.putIfAbsent(columnName, new ArrayList<>());
colorMap.get(columnName).add(strTextColor);
colorMap.get(columnName).add(strBackgroundColor);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return colorMap;
}
Note: I've provided the code based on your request for code translation. If you have any questions or need further assistance, feel free to ask.
英文:
I have an xml document, say of the format :
<DynamicReport>
<DynamicReportDefId>501</DynamicReportDefId>
<DynamicReportDefName>Test report</DynamicReportDefName>
<DynamicReportDefSource>Live</DynamicReportDefSource>
<IsPrivate>false</IsPrivate>
<showSummaryRowsOnly>false</showSummaryRowsOnly>
<Limit>false</Limit>
<LimitRows/>
<InvUserId/>
<Version>0</Version>
<Category/>
<Columns class="array">
<Column>
<TableName>vwdynfirms</TableName>
<ColumnName>firmlongname</ColumnName>
<FormattingInfo>
<Header>
<DisplayName>Firm Long Name</DisplayName>
<FontInfo>
<Font/>
<FontSize/>
<IsBold/>
<IsItalic/>
<IsUnderline/>
<TextColor/>
<BackgroundColor/>
</FontInfo>
<AlignmentInfo>
<HorizontalAlignment/>
<VerticalAlignment/>
</AlignmentInfo>
<BorderInfo>
<BorderLeft/>
<BorderRight/>
<BorderTop/>
<BorderBottom/>
</BorderInfo>
</Header>
<Detail>
<FontInfo>
<Font/>
<FontSize/>
<IsBold/>
<IsItalic/>
<IsUnderline/>
<TextColor/>
<BackgroundColor/>
</FontInfo>
<AlignmentInfo>
<HorizontalAlignment/>
<VerticalAlignment/>
</AlignmentInfo>
<BorderInfo>
<BorderLeft/>
<BorderRight/>
<BorderTop/>
<BorderBottom/>
</BorderInfo>
<DisplayPattern/>
</Detail>
</FormattingInfo>
</Column>
<Column>
<TableName>vwdynfirms</TableName>
<ColumnName>firmname</ColumnName>
<FormattingInfo>
<Header>
<DisplayName>Firm Name</DisplayName>
<FontInfo>
<Font>Calibri</Font>
<FontSize>14</FontSize>
<IsBold>true</IsBold>
<IsItalic/>
<IsUnderline/>
<TextColor>#FF0080</TextColor>
<BackgroundColor>#FFFFFF</BackgroundColor>
</FontInfo>
<AlignmentInfo>
<HorizontalAlignment>left</HorizontalAlignment>
<VerticalAlignment>bottom</VerticalAlignment>
</AlignmentInfo>
<BorderInfo>
<BorderLeft/>
<BorderRight/>
<BorderTop/>
<BorderBottom>true</BorderBottom>
</BorderInfo>
</Header>
<Detail>
<FontInfo>
<Font/>
<FontSize/>
<IsBold/>
<IsItalic/>
<IsUnderline/>
<TextColor/>
<BackgroundColor/>
</FontInfo>
<AlignmentInfo>
<HorizontalAlignment/>
<VerticalAlignment/>
</AlignmentInfo>
<BorderInfo>
<BorderLeft/>
<BorderRight/>
<BorderTop/>
<BorderBottom/>
</BorderInfo>
<DisplayPattern/>
</Detail>
</FormattingInfo>
</Column>
</Columns>
</DynamicReport>
From this xml document, I want to get the TextColor
and the BackgroundColor
for a particular Column
and then store them in a map. I am expecting the map to be of the format Map<String>, List<String>
where the key is the ColumnName
and the list of strings would be the two colors (TextColor
and the BackgroundColor
) as the values for the column in the map for now.
I have written the code, wherein I am not returning anything until I am able to get the column name by traversing back :
//Getting the column from the colors for all the columns
public static void getColors(Document doc)
{
String expressionGroupedCol = "/DynamicReport/Columns/Column/FormattingInfo/Header/FontInfo";
XPath xPath = XPathFactory.newInstance().newXPath();
try {
NodeList nodeList = (NodeList) xPath.compile(expressionGroupedCol).evaluate(
doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++)
{
Node nNode = nodeList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element) nNode;
String strTextColor = eElement.getElementsByTagName("TextColor").item(0).getTextContent();
System.out.println(strTextColor);
String strBackgroundColor = eElement.getElementsByTagName("BackgroundColor").item(0).getTextContent();
System.out.println(strBackgroundColor);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
I am able to get the text color and background color. But I don't have a clue as to how to traverse back and get the corresponding column name and add that to the map. Any help would be appreciated. Thanks in advance.
答案1
得分: 1
虽然这不是你所要求的内容,但我认为你最好使用XPath来定位每个<Column>
元素,然后重用你的XPath
实例来定位相关的数据:
public static Map<String, List<String>> getColors(Document doc) {
XPath xpath = XPathFactory.newInstance().newXPath();
try {
NodeList columns = (NodeList)
xpath.evaluate("/DynamicReport/Columns/Column", doc,
XPathConstants.NODESET);
int numColumns = columns.getLength();
Map<String, List<String>> map = new LinkedHashMap<>(numColumns);
for (int i = 0; i < numColumns; i++) {
Node column = columns.item(i);
String columnName = xpath.evaluate("ColumnName", column);
Node fontInfo = (Node) xpath.evaluate(
"FormattingInfo/Header/FontInfo", column,
XPathConstants.NODE);
String textColor =
xpath.evaluate("TextColor", fontInfo);
String backgroundColor =
xpath.evaluate("BackgroundColor", fontInfo);
map.put(columnName, Arrays.asList(textColor, backgroundColor));
}
return map;
} catch (XPathException e) {
throw new RuntimeException(e);
}
}
如果你没有传递XPathConstants
常量给XPath.evaluate
,则返回匹配节点的文本内容,这恰好是你获取字符串所需的内容。
英文:
While this isn’t what you asked for, I think you would be better off using an XPath to locate each <Column>
element, then reusing your XPath
instance to locate the data relative to it:
public static Map<String, List<String>> getColors(Document doc) {
XPath xpath = XPathFactory.newInstance().newXPath();
try {
NodeList columns = (NodeList)
xpath.evaluate("/DynamicReport/Columns/Column", doc,
XPathConstants.NODESET);
int numColumns = columns.getLength();
Map<String, List<String>> map = new LinkedHashMap<>(numColumns);
for (int i = 0; i < numColumns; i++) {
Node column = columns.item(i);
String columnName = xpath.evaluate("ColumnName", column);
Node fontInfo = (Node) xpath.evaluate(
"FormattingInfo/Header/FontInfo", column,
XPathConstants.NODE);
String textColor =
xpath.evaluate("TextColor", fontInfo);
String backgroundColor =
xpath.evaluate("BackgroundColor", fontInfo);
map.put(columnName, Arrays.asList(textColor, backgroundColor));
}
return map;
} catch (XPathException e) {
throw new RuntimeException(e);
}
}
If you don’t pass an XPathConstants constant to XPath.evaluate
, the text content of the matching node is returned, which turns out to be exactly what you want for obtaining your Strings.
答案2
得分: 0
如果你不介意作弊的话
Element column = (Element)(eElement.getParentNode().getParentNode().getParentNode());
英文:
If you don't mind cheesing it
Element column = (Element)(eElement.getParentNode().getParentNode().getParentNode());
答案3
得分: 0
我能够获取文本颜色和背景颜色。但是我不知道如何遍历回去获取相应的列名,并将其添加到映射中。
只需评估此XPath表达式(使用您当前通过此路径找到的上下文节点:/DynamicReport/Columns/Column/FormattingInfo/Header/FontInfo
):
ancestor::Column[1]/ColumnName
英文:
> I am able to get the text color and background color. But I don't have
> a clue as to how to traverse back and get the corresponding column
> name and add that to the map.
Just evaluate this XPath expression (using your current context node that you found with this: /DynamicReport/Columns/Column/FormattingInfo/Header/FontInfo
):
ancestor::Column[1]/ColumnName
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论