您好我嘗試在C#中實現撒克遜擴展。我使用saxon9he界面。擴展本身工作正常,但現在我想使用XPath表達式從節點獲取值。我把它分解到相關的代碼部分(其餘的工作正常)。撒克遜擴展:XdmNode上的XPath
擴展名有兩個參數。第一個是字符串,第二個是節點集。
public override IXdmEnumerator Call(IXdmEnumerator[] arguments, DynamicContext context)
{
if (arguments.Length == 2)
{
arguments[0].MoveNext();
string text = (arguments[0].Current as XdmAtomicValue).Value as string;
IXdmEnumerator enumerator = arguments[1];
while (enumerator.MoveNext())
{
XdmNode node = (XdmNode)enumerator.Current;
// how can I get values from node here by using XPath expressions?
// e.g. I want the value of the attribute "type" of the subnode "xy"
// XPath would be something like this: "./xy/@type"
text = text.Replace(node.NodeName.LocalName, node.StringValue);
}
var result = new XdmAtomicValue(text);
return (IXdmEnumerator)result.GetEnumerator();
}
...
}
3條評論在中間顯示我的問題。我想通過XPath表達式來訪問子節點,屬性等等。這是一個簡化版本。 XPath應該稍後作爲附加參數傳遞。所以它不是一個固定的XPath表達式,我可以轉換爲代碼。我真的需要一個XPath評估器。
我看到了一個解決方案,從處理器創建一個XPathEvaluator。但是我現在沒有處理器,或者我呢?
感謝您的幫助。
這裏是解決方案(感謝Michael):
var configuration = context.Implementation.getConfiguration();
var processor = (Processor)configuration.getProcessor();
var xpathCompiler = processor.NewXPathCompiler();
while (enumerator.MoveNext())
{
XdmNode node = (XdmNode)enumerator.Current;
var keyResult = xpathCompiler.Evaluate(searchXPath, node);
var valueResult = xpathCompiler.Evaluate(replaceXPath, node);
string key = "";
string value = "";
if (keyResult is XdmAtomicValue)
key = (string)(keyResult as XdmAtomicValue).Value;
else if (keyResult is XdmNode)
key = (string)(keyResult as XdmNode).StringValue;
if (valueResult is XdmAtomicValue)
value = (string)(valueResult as XdmAtomicValue).Value;
else if (valueResult is XdmNode)
value = (string)(valueResult as XdmNode).StringValue;
if (string.IsNullOrWhiteSpace(key) || value == null)
continue;
text = text.Replace(key, value);
}
解決方案撒克遜9.7:
上述解決方案不適用於撒克遜9.7工作了。在這種情況下,我將處理器傳遞給擴展類,並在那裏註冊擴展時從那裏傳遞給擴展調用類。
public static void RegisterSaxonExtensions(Saxon.Api.Processor processor)
{
processor.RegisterExtensionFunction(new MyExtension1(processor));
processor.RegisterExtensionFunction(new MyExtension2(processor));
}
...
public class MyExtension1 : Saxon.Api.ExtensionFunctionDefinition
{
private Saxon.Api.Processor processor = null;
public MyExtension1(Saxon.Api.Processor processor)
{
this.processor = processor;
}
public override ExtensionFunctionCall MakeFunctionCall()
{
return new MyExtension1Call(this.processor);
}
...
}
public class MyExtension1Call : Saxon.Api.ExtensionFunctionCall
{
private Saxon.Api.Processor processor = null;
public MyExtension1Call(Saxon.Api.Processor processor)
{
this.processor = processor;
}
public override IXdmEnumerator Call(IXdmEnumerator[] arguments, DynamicContext context)
{
if (arguments.Length == 2)
{
arguments[0].MoveNext();
string text = (arguments[0].Current as XdmAtomicValue).Value as string;
IXdmEnumerator enumerator = arguments[1];
var xpathCompiler = this.processor.NewXPathCompiler();
while (enumerator.MoveNext())
{
XdmNode node = (XdmNode)enumerator.Current;
var keyResult = xpathCompiler.Evaluate(searchXPath, node);
var valueResult = xpathCompiler.Evaluate(replaceXPath, node);
string key = "";
string value = "";
if (keyResult is XdmAtomicValue)
key = (string)(keyResult as XdmAtomicValue).Value;
else if (keyResult is XdmNode)
key = (string)(keyResult as XdmNode).StringValue;
if (valueResult is XdmAtomicValue)
value = (string)(valueResult as XdmAtomicValue).Value;
else if (valueResult is XdmNode)
value = (string)(valueResult as XdmNode).StringValue;
if (string.IsNullOrWhiteSpace(key) || value == null)
continue;
text = text.Replace(key, value);
}
var result = new XdmAtomicValue(text);
return (IXdmEnumerator)result.GetEnumerator();
}
}
}
非常感謝! :)現在它工作。 –
嗨邁克爾。我從撒克遜HE 9.5切換到HE 9.7。現在我的代碼失敗了,因爲'configuration.getProcessor()'現在返回一個'net.sf.saxon.s9api.Processor'而不是'Saxon.Api.Processor'。我猜接口是相似的,但是我可以用'Saxon.Api'命名空間的類來處理嗎?還是應該調整代碼以使用'net.sf.saxon.s9api'命名空間中的代碼? –
如果後者是這種情況:如何將'Saxon.Api.XdmNode'轉換爲'net.sf.saxon.s9api.XdmItem',其中'net.sf.saxon.s9api.XPathCompiler.evaluate'方法需要作爲輸入?我怎樣才能將'evaluate'方法('net.sf.saxon.s9api.XdmValue')的結果轉換回'Saxon.Api.XdmValue'? –