EXEC sp_serveroption 'YOURSERVERNAME', 'DATA ACCESS', TRUE
SELECT *
INTO #tmpTable
FROM OPENQUERY(YOURSERVERNAME, 'EXEC db.schema.sproc 1')
Хорошо, поэтому я укусил пулю и нашел время, чтобы написать программу Java, которая делает то, что я хочу. Ниже приведен рабочий метод, вызываемый моим методом main (), который выполняет эту работу, на случай, если это будет полезно кому-то еще в будущем:
/**
* Takes an input XML file, replaces the text value of the node specified by an XPath parameter, and writes a new
* XML file with the updated data.
*
* @param inputXmlFilePathName
* @param outputXmlFilePathName
* @param elementXpath
* @param elementValue
* @param replaceAllFoundElements
*/
public static void replaceElementValue(final String inputXmlFilePathName,
final String outputXmlFilePathName,
final String elementXpathExpression,
final String elementValue,
final boolean replaceAllFoundElements)
{
try
{
// get the template XML as a W3C Document Object Model which we can later write back as a file
InputSource inputSource = new InputSource(new FileInputStream(inputXmlFilePathName));
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
Document document = documentBuilderFactory.newDocumentBuilder().parse(inputSource);
// create an XPath expression to access the element's node
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
XPathExpression xpathExpression = xpath.compile(elementXpathExpression);
// get the node(s) which corresponds to the XPath expression and replace the value
Object xpathExpressionResult = xpathExpression.evaluate(document, XPathConstants.NODESET);
if (xpathExpressionResult == null)
{
throw new RuntimeException("Failed to find a node corresponding to the provided XPath.");
}
NodeList nodeList = (NodeList) xpathExpressionResult;
if ((nodeList.getLength() > 1) && !replaceAllFoundElements)
{
throw new RuntimeException("Found multiple nodes corresponding to the provided XPath and multiple replacements not specified.");
}
for (int i = 0; i < nodeList.getLength(); i++)
{
nodeList.item(i).setTextContent(elementValue);
}
// prepare the DOM document for writing
Source source = new DOMSource(document);
// prepare the output file
File file = new File(outputXmlFilePathName);
Result result = new StreamResult(file);
// write the DOM document to the file
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(source, result);
}
catch (Exception ex)
{
throw new RuntimeException("Failed to replace the element value.", ex);
}
}
Я запускаю программу следующим образом:
$ java -cp xmlutility.jar com.abc.util.XmlUtility input.xml output.xml '//name/text()' JAMES
sed
не будет простым инструментом для использования многострочной замены. Их можно реализовать с помощью команды N
и некоторой рекурсии, проверяя после чтения в каждой строке, было ли найдено закрытие тега ... но это некрасиво, и вы никогда не вспомните об этом.
Конечно, на самом деле самым безопасным будет анализ xml и замена тегов, но если вы знаете, что не столкнетесь с какими-либо проблемами, вы можете попробовать следующее:
perl -p -0777 -e 's@<xyz>.*?</xyz>@<xyz>new-value</xyz>@sg' <xml-file>
Нарушение этого:
-p
указывает ему выполнить цикл по вводу, а print -0777
указывает ему использовать конец файла в качестве разделителя входных данных, так что он получит все за один slurp -e
означает то, что я хочу, чтобы вы сделали И сама замена:
@
в качестве разделителя, чтобы не было необходимости экранировать /
*?
, нежадную версию, чтобы сопоставить всего лишь возможно, поэтому мы не дойдем до последнего появления
в файле s
, чтобы разрешить .
] сопоставление новой строки (для получения значений многострочного тега) g
, чтобы сопоставить шаблон несколько раз Tada! Результат будет выведен на стандартный вывод - как только вы убедитесь, что он делает то, что вы хотите, добавьте параметр -i
, чтобы указать ему отредактировать файл на месте.
s
, чтобы разрешить .
сопоставление новой строки (для получения значений многострочного тега) g
, чтобы сопоставить шаблон несколько раз Tada! Результат будет выведен на стандартный вывод - как только вы убедитесь, что он делает то, что вы хотите, добавьте параметр -i
, чтобы указать ему отредактировать файл на месте.
s
, чтобы разрешить .
сопоставление новой строки (для получения значений многострочного тега) g
, чтобы сопоставить шаблон несколько раз Tada! Результат будет выведен на стандартный вывод - как только вы убедитесь, что он делает то, что вы хотите, добавьте параметр -i
, чтобы указать ему отредактировать файл на месте.
Ненавижу скептически относиться к XML, но XML не является обычным. С регулярным выражением, вероятно, будет больше проблем, чем оно того стоит. См. Здесь для получения дополнительной информации: Использование регулярных выражений C # для замены содержимого XML-элементов
В конце концов, ваша мысль о простой программе Java может быть хорошей. Преобразование XSLT может быть проще, если вы хорошо знаете XSLT. Если вы знаете Perl ... это путь, ИМХО.
Сказав это, если вы выберете Regex и ваша версия sed поддерживает расширенные регулярные выражения, вы можете сделать его многострочным с помощью / g. Другими словами, поместите / g в конец регулярного выражения, и он будет соответствовать вашему шаблону, даже если они находятся на нескольких строках.
Также. предложенное вами регулярное выражение является «жадным». Он будет захватывать самую большую группу символов, потому что ". " будет соответствовать от первого вхождения до последнего. Вы можете сделать его «ленивым», изменив подстановочный знак на «. ?». Если поставить вопросительный знак после звездочки, это означает, что он соответствует только одному набору из до.
будет соответствовать от первого до последнего появления. Вы можете сделать его «ленивым», изменив подстановочный знак на «. ?». Если поставить вопросительный знак после звездочки, это означает, что он соответствует только одному набору из до. будет соответствовать от первого до последнего появления. Вы можете сделать его «ленивым», изменив подстановочный знак на «. ?». Если поставить вопросительный знак после звездочки, это означает, что он соответствует только одному набору из до.Я пытался сделать то же самое и наткнулся на скрипт [gu] awk, который его добился.
BEGIN { FS = "[<|>]" }
{
if ($2 == "xyz") {
sub($3, "replacement")
}
print
}